工厂模式分为三大类
目的:
工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。
一、简单工厂
组成如下:
(1) 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现。
(2) 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。
(3) 具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。
具体例子:
抽象产品、具体产品角色类定义如下:
package com.open.design.factory; public class SimpleFactoryData { //2.抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。 public interface Car { void printName(); } //3.具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。 public static class Benz implements Car { @Override public void printName() { System.out.println("i am Benz."); } } public static class BMW implements Car { @Override public void printName() { System.out.println("i am BMW."); } } public static class Audi implements Car { @Override public void printName() { System.out.println("i am Audi."); } } public static class Tesla implements Car { @Override public void printName() { System.out.println("i am Tesla."); } } }
package com.open.design.factory; import com.open.design.factory.SimpleFactoryData.Car; //1.工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现 public class SimpleFactory { public static Car produce(String carName) { Car car=null; if("Benz".equals(carName)) { car=new SimpleFactoryData.Benz(); } else if("BMW".equals(carName)) { car=new SimpleFactoryData.BMW(); } else if("Audi".equals(carName)) { car=new SimpleFactoryData.Audi(); } else if("Tesla".equals(carName)) { car=new SimpleFactoryData.Tesla(); } return car; } }
package com.open.design.factory; import com.open.design.factory.SimpleFactoryData.Car; public class SimpleFactoryTest { /** * @param args */ public static void main(String[] args) { Car car=SimpleFactory.produce("Benz"); car.printName(); car=SimpleFactory.produce("BMW"); car.printName(); car=SimpleFactory.produce("Audi"); car.printName(); car=SimpleFactory.produce("Tesla"); car.printName(); } }
优点与缺点:
简单工厂方法的优点是当在系统中引入新产品时不必修改客户端,但需要个修改工厂类。这个工厂类集中了所有产品创建逻辑,形成了一个无所不知的全能类(也称上帝类),如果此类出问题了,整个应用都受大影响。
二、工厂方法模式(也称多态工厂)
组成如下:
(1)抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
(2)具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
(3)抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
(4)具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。
具体例子如下:
抽象产品、具体产品角色类定义如下:
package com.open.design.factory; public class PolymorphicData { //3.抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。 public interface Car { void printName(); } //4.具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。 public static class Sedan implements Car { @Override public void printName() { System.out.println("i am Sedan."); } } public static class Train implements Car { @Override public void printName() { System.out.println("i am Train."); } } public static class Bike implements Car { @Override public void printName() { System.out.println("i am Bike."); } } }
抽象工厂、具体工厂类定义如下:
package com.open.design.factory; import com.open.design.factory.PolymorphicData.Car; public class PolymorphicFactory { //1.抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。 public static abstract class CarFactory { abstract Car createCar(); } //2.具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。 public static class SedanFactory extends CarFactory { public Car createCar() { return new PolymorphicData.Sedan(); }; } public static class TrainFactory extends CarFactory { public Car createCar() { return new PolymorphicData.Train(); }; } public static class BikeFactory extends CarFactory { public Car createCar() { return new PolymorphicData.Bike(); }; } }
package com.open.design.factory; import com.open.design.factory.PolymorphicData.Car; import com.open.design.factory.PolymorphicFactory.BikeFactory; import com.open.design.factory.PolymorphicFactory.CarFactory; import com.open.design.factory.PolymorphicFactory.SedanFactory; import com.open.design.factory.PolymorphicFactory.TrainFactory; public class PolymorphicTest { /** * @param args */ public static void main(String[] args) { CarFactory factory=new SedanFactory(); Car car =factory.createCar(); car.printName(); factory=new TrainFactory(); car =factory.createCar(); car.printName(); factory=new BikeFactory(); car =factory.createCar(); car.printName(); } }
优点与缺点:
当在系统中引入新产品时,既不必修改客户端,又不必修改具体工厂角色可以较好的对系统进行扩展。但是当产品种类繁多时,工厂类成倍数增长(因为种类越多,与之对应的工厂类也越多)
在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建的工作交给子类去做。这个核心工厂则变为抽象工厂角色,仅负责给出具工厂子类必须实现的接口,而不接触哪一产品创建的细节。这种抽象的结果,使这种工厂方法模式可以用来允许系统不修改具体工厂角色的情况下引进新产品,这一特点无疑使得工厂模式具有超过简单工厂模式的优越性。
三、抽象工厂
组成与工厂方法模式一致,只不过抽象工厂是针对多个产品等级结构,工厂方法是针对一个产品等级结构。(产品族:是指位于不同产品等级结构中,功能相关联的产品组成的家族。比如AMD的CPU和ADM芯片的主板,组成一个家族。Intel的CPU和Intel芯片的主板,又组成一个家族。而这两个家族都来自于两个产品等级:CPU,主板。)
具体例子如下:
抽象产品、具体产品角色类定义如下:
package com.open.design.factory; public class AbstractFactryCar { //2.抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。 public interface Car { void printName(); } //3.具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。 public static class Benz implements Car { @Override public void printName() { System.out.println("i am Benz."); } } public static class BMW implements Car { @Override public void printName() { System.out.println("i am BMW."); } } public static class Audi implements Car { @Override public void printName() { System.out.println("i am Audi."); } } public static class Tesla implements Car { @Override public void printName() { System.out.println("i am Tesla."); } } }
package com.open.design.factory; public class AbstractFactryHouse { //2.抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。 public interface House { void printHouseName(); } //3.具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。 public static class Villa implements House { @Override public void printHouseName() { System.out.println("i am Villa."); } } public static class TileRoofedHouse implements House { @Override public void printHouseName() { System.out.println("i am TileRoofedHouse."); } } public static class CommodityHouse implements House { @Override public void printHouseName() { System.out.println("i am CommodityHouse."); } } }
package com.open.design.factory; import com.open.design.factory.AbstractFactryCar.Car; import com.open.design.factory.AbstractFactryHouse.House; public class AbstractFactry { //抽象工厂类 public static abstract class AbsDream { public abstract Car createCar(); public abstract House createHouse(); } //2.具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。 public static class DreamAFactory extends AbsDream { public Car createCar() { return new AbstractFactryCar.Benz(); }; public House createHouse() { return new AbstractFactryHouse.TileRoofedHouse(); }; } public static class DreamBFactory extends AbsDream { public Car createCar() { return new AbstractFactryCar.Audi(); }; public House createHouse() { return new AbstractFactryHouse.CommodityHouse(); }; } public static class DreamCFactory extends AbsDream { public Car createCar() { return new AbstractFactryCar.Tesla(); }; public House createHouse() { return new AbstractFactryHouse.Villa(); }; } }
package com.open.design.factory; import com.open.design.factory.AbstractFactry.AbsDream; import com.open.design.factory.AbstractFactryCar.Car; import com.open.design.factory.AbstractFactryHouse.House; public class AbstractFactryTest { /** * @param args */ public static void main(String[] args) { AbsDream dream = new AbstractFactry.DreamAFactory(); Car car =dream.createCar(); House house=dream.createHouse(); car.printName(); house.printHouseName(); //------------------- dream = new AbstractFactry.DreamBFactory(); car =dream.createCar(); house=dream.createHouse(); car.printName(); house.printHouseName(); //------------------- dream = new AbstractFactry.DreamCFactory(); car =dream.createCar(); house=dream.createHouse(); car.printName(); house.printHouseName(); } }
优点与缺点:
抽象工厂模式面对的问题是多产品等级结构的系统设计。抽象工厂模式的每个工厂创造出来的都是一族产品,而不是一个或者一组。
四、动态工厂
组成与简单工厂类似。
具体例子:
抽象产品、具体产品角色类定义如下:
package com.open.design.factory; public class DynamicFactoryData { //2.抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。 public interface Car { void printName(); } //3.具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。 public static class Benz implements Car { @Override public void printName() { System.out.println("i am Benz."); } } public static class BMW implements Car { @Override public void printName() { System.out.println("i am BMW."); } } public static class Audi implements Car { @Override public void printName() { System.out.println("i am Audi."); } } public static class Tesla implements Car { @Override public void printName() { System.out.println("i am Tesla."); } } }
package com.open.design.factory; import java.lang.reflect.Constructor; import com.open.design.factory.DynamicFactoryData.Car; public class DynamicFactory { public static Car produce(String carName) { ClassLoader mClassLoader=DynamicFactory.class.getClassLoader(); try { Class<?> mClass = mClassLoader.loadClass(carName); Constructor<?>[] mConstructor=mClass.getConstructors(); return (Car) mConstructor[0].newInstance(); } catch (Exception e) { e.printStackTrace(); } return null; } }
package com.open.design.factory; import com.open.design.factory.DynamicFactoryData.Car; public class DynamicFactoryTest { /** * @param args */ public static void main(String[] args) { Car car=DynamicFactory.produce("com.open.design.factory.DynamicFactoryData$Benz"); car.printName(); car=DynamicFactory.produce("com.open.design.factory.DynamicFactoryData$BMW"); car.printName(); car=DynamicFactory.produce("com.open.design.factory.DynamicFactoryData$Audi"); car.printName(); car=DynamicFactory.produce("com.open.design.factory.DynamicFactoryData$Tesla"); car.printName(); } }
优点与缺点:
简单模式的优化版,代码简洁。
总结:
(1)简单工厂模式是由一个具体的类去创建其他类的实例。 (对于增加新的产品,无能为力)
(2)工厂方法模式是有一个抽象的父类定义公共接口,子类负责生成具体的对象,这样做的目的是将类的实例化操作延迟到子类中完成。 (支持增加新产品)
(3)抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无须指定他们具体的类。它针对的是有多个产品的等级结构。而工厂方法模式针对的是一个产品的等级结构。(对于增加新的产品,无能为力;支持增加产品族)
本文代码地址:https://github.com/zz7zz7zz/design-pattern
参考博文:http://www.cnblogs.com/forlina/archive/2011/06/21/2086114.html
http://www.cnblogs.com/devinzhang/archive/2011/12/19/2293160.html