1.静态工厂方法
只给司机一辆车
package com.bjsxt.dp.factory; import java.util.ArrayList; import java.util.List; public class Car { private static Car car = new Car();// 单例 private static List<Car> cars = new ArrayList<Car>();// 多例。连接池就是 private Car() { } /** * 静态工厂方法,在一个方法里面控制了产生对象的逻辑,都可以把该方法称为工厂相关的方法,又因为该方法是静态的,所以叫静态工厂方法 * * @return */ public static Car getInstance() { return car; } public void run() { System.out.println("冒着烟奔跑中car..."); }; }
package com.bjsxt.dp.factory; public class Test { public static void main(String[] args) { // TODO Auto-generated method stub Car car = Car.getInstance(); Car car2 = Car.getInstance(); if(car==car2) System.out.println("same car"); car.run(); } }
2.简单工厂模式
1.目标:要控制任意定制交通工具的类型和生产过程
目标有两层意思(1)任意类型 (2)生产模式,所以对应的,要这两个层面上抽象(Movable,VehicleFactory),利用接口,实现多态
2.类结构
1.Interface Movable.java
2.Car.java
3.Plane.java
4.Interface VehicleFactory.java
5.CarFactory.java
6.PlaneFactory.java
3.代码
1.Movable.java
package com.bjsxt.dp.factory; public interface Moveable { void run(); }
2.Car.java
package com.bjsxt.dp.factory; public class Car implements Moveable { @Override public void run() { System.out.println("冒着烟奔跑中car..."); }; }
3.Plane.java
package com.bjsxt.dp.factory; public class Plane implements Moveable { @Override public void run() { // TODO Auto-generated method stub System.out.println("扇着翅膀前进中..."); } }
4.VehicleFactory.java
package com.bjsxt.dp.factory; public abstract class VehicleFactory { abstract Moveable create(); }
5.CarFactory.java
package com.bjsxt.dp.factory; public class CarFactory extends VehicleFactory{ @Override public Moveable create() { // TODO Auto-generated method stub return new Car(); } }
6.PlaneFactory.java
package com.bjsxt.dp.factory; public class PlaneFactory extends VehicleFactory { @Override Moveable create() { // TODO Auto-generated method stub return new Plane(); } }
7.Test.java
package com.bjsxt.dp.factory; public class Test { public static void main(String[] args) { // TODO Auto-generated method stub VehicleFactory factory = new CarFactory(); Moveable m = factory.create(); m.run(); } }
这样系统就可以产生扩展,既可以扩展交通工具,又可以控制生产过程。
public class Broom implements Moveable { @Override public void run() { System.out.println("一路沙尘暴飞奔而来broom..."); } }
public class BroomFactory extends VehicleFactory { @Override Moveable create() { return new Broom(); } }
public class Test { public static void main(String[] args) { VehicleFactory factory = new BroomFactory(); Moveable m = factory.create(); m.run(); } }
3.抽象工厂模式
系列产品(车、武器、食物)
首先,我们新建了一个Car类,一个AK47类,还有一个Apple类。
package com.bjsxt.dp.abstractFactory; public class Car { public void run() { System.out.println("冒着烟奔跑中car..."); } }
package com.bjsxt.dp.abstractFactory; public class AK47 { public void shoot(){ System.out.println("哒哒哒..."); } }
package com.bjsxt.dp.abstractFactory; public class Apple { public void printName() { System.out.println("apple"); } }
然后我们新建一个用户测试类,他有一辆车,一把AK47,一个苹果。
package com.bjsxt.dp.abstractFactory; public class Test { public static void main(String[] args) { Car car = new Car(); car.run(); AK47 ak47 = new AK47(); ak47.shoot(); Apple apple = new Apple(); apple.printName(); } }
这里的车,AK47,苹果都是分别new出来的,如果我们想要一次性的定制这些东西就需要用到抽象工厂模式。
首先,我们想到要新建一个工厂,取名为DefaultFactory.
package com.bjsxt.dp.abstractFactory; public class DefaultFactory { public Car createCar(){ return new Car(); } public AK47 createAK47(){ return new AK47(); } public Apple createApple(){ return new Apple(); } }
这样的话我们的用户测试类就可以改成这样:
package com.bjsxt.dp.abstractFactory; public class Test { public static void main(String[] args) { DefaultFactory factory = new DefaultFactory(); Car car = factory.createCar(); car.run(); AK47 ak47 = factory.createAK47(); ak47.shoot(); Apple apple = factory.createApple(); apple.printName(); } }
如果我想把上面的一系列产品都替换掉,只要来一个新的工厂就可以了,如 MagicFactory:
package com.bjsxt.dp.abstractFactory; public class MagicFactory { public Broom createBroom(){ return new Broom(); } public MagicStick createMagicStrick(){ return new MagicStick(); } public MushRoom createMushRoom(){ return new MushRoom(); } }
那么现在问题来了,如果我想把测试类中的DefaultFactory换成MagicFactory,那么下面的这些方法也要全部都改,太麻烦了,不想改下面的这些方法怎么办呢?
解决方法,产生一个工厂的父类,abstractFactory
package com.bjsxt.dp.abstractFactory; public abstract class AbstractFactory { public abstract Vehicle createVehicle(); public abstract Weapon createWeapon(); public abstract Food createFood(); }
package com.bjsxt.dp.abstractFactory; public abstract class Vehicle { public abstract void run(); }
package com.bjsxt.dp.abstractFactory; public abstract class Weapon { public abstract void shoot(); }
package com.bjsxt.dp.abstractFactory; public abstract class Food { public abstract void printName(); }
有了上面的这些抽象类,就可以继承上面的这些类。
package com.bjsxt.dp.abstractFactory; public class DefaultFactory extends AbstractFactory{ @Override public Vehicle createVehicle() { return new Car(); } @Override public Weapon createWeapon() { return new AK47(); } @Override public Food createFood() { return new Apple(); } }
package com.bjsxt.dp.abstractFactory; public class MagicFactory extends AbstractFactory { @Override public Vehicle createVehicle() { return new Broom(); } @Override public Weapon createWeapon() { return new MagicStick(); } @Override public Food createFood() { return new MushRoom(); } }
package com.bjsxt.dp.abstractFactory; public class AK47 extends Weapon{ public void shoot(){ System.out.println("哒哒哒..."); } }
package com.bjsxt.dp.abstractFactory; public class Apple extends Food{ public void printName() { System.out.println("apple"); } }
package com.bjsxt.dp.abstractFactory; public class Car extends Vehicle { @Override public void run() { System.out.println("冒着烟奔跑中car..."); } }
package com.bjsxt.dp.abstractFactory; public class Broom extends Vehicle { @Override public void run() { System.out.println("一路沙尘暴飞奔而来broom..."); } }
package com.bjsxt.dp.abstractFactory; public class MushRoom extends Food{ @Override public void printName() { System.out.println("mushroom..."); } }
package com.bjsxt.dp.abstractFactory; public class MagicStick extends Weapon { @Override public void shoot() { System.out.println("fire hu hu"); } }
test类
package com.bjsxt.dp.abstractFactory; public class Test { public static void main(String[] args) { AbstractFactory factory = new DefaultFactory(); // AbstractFactory factory = new MagicFactory(); Vehicle v = factory.createVehicle(); v.run(); Weapon w = factory.createWeapon(); w.shoot(); Food f = factory.createFood(); f.printName(); } }
整个体系结构如下图:
如游戏里面的换皮肤功能,如果换个皮肤,界面上的很多功能及按钮都变了。
总结:抽象工厂是生产了一系列产品,如果想换掉这一系列产品的时候,或者是想在这一些列产品的功能上进行扩展,想产生新的系列产品以及想对这一系列产品的生产过程进行控制,用抽象工厂。
简单工厂的问题在于产生产品系列的时候会造成工厂泛滥,而抽象工厂的问题在于在产生新的产品品种的时候,改动的地方会很多。
4.Spring中的工厂
现在又一个moveable接口,有两个实现类。
package com.bjsxt.dp.springfactory; public interface Moveable { void run(); }
package com.bjsxt.dp.springfactory; public class Car implements Moveable { public void run() { System.out.println("冒着烟奔跑中car..."); } }
public class Train implements Moveable { @Override public void run() { System.out.println("小火车呜呜呜"); } }
此时,可以在测试类中,new car()或者new train().
public class Test { public static void main(String[] args) throws Exception { // Moveable m = new Train(); Moveable m = new Car(); m.run(); } }
现在的问题是能不能不要new,因为new源代码还是要更改,能不能改到配置文件里。
1.利用properties文件配置
VehicleType=factory.Train
package factory; import factory.Car; import factory.Moveable; import java.util.Properties; public class Test { public static void main(String[] args) throws Exception { Properties pros = new Properties(); pros.load(Test.class.getClassLoader().getResourceAsStream("spring.properties")); String vehicleTypeName = pros.getProperty("VehicleType"); System.out.println(vehicleTypeName); Object o = Class.forName(vehicleTypeName).newInstance(); Moveable m = (Moveable)o; m.run(); } }
此时,要是想改成car,则只要改配置文件就可以了。VehicleType=factory.Car
2.spring中的Bean工厂
1.先导入spring的jar包及spring框架需要的logging jar包
2.spring中的配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="v" class="com.bjsxt.dp.springfactory.Car"> </bean> <!-- 相当于 //v=com.bjsxt.spring.factory.factory.Car --> </beans>
3.测试类
package com.bjsxt.dp.springfactory; import org.springframework.beans.factory.BeanFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { BeanFactory f = new ClassPathXmlApplicationContext("applicationContext.xml"); Object o = f.getBean("v"); Moveable m = (Moveable) o; m.run(); } }