结合实例分析简单工厂模式&工厂方法模式&抽象工厂模式的区别
2014-10-16 11:15
309 查看
之前写过一篇关于工厂模式(Factory Pattern)的随笔,里面分析了简单工厂模式,但对于工厂方法和抽象工厂的分析较为简略。这里重新分析分析三者的区别,工厂模式是java设计模式中比较简单的一个设计模式,但很多地方都用到了工厂模式,(如解析xml中,jdbc连接数据库等)利用好工厂模式对程序的设计很有用处。工厂模式在一些设计模式的书中分为简单工厂模式,工厂方法模式和抽象工厂模式三类。也有把工厂方法模式划分到抽象工厂模式的,认为工厂方法是抽象工厂模式的特例的一种,就是只有一个要实现的产品接口。下面结合例子分析三者的区别。
首先是简单工厂模式,这里以工厂生产产品为例。
产品类的共同接口
产品类A
产品类B
工厂类
客户端
控制台输出结果:
简单工厂模式实现了生成产品类的代码跟客户端代码分离,在工厂类中你可以添加所需的生成产品的逻辑代码,但是问题来了,优秀的java代码是符合“开放-封闭”原则的,也就是说对扩展开发,对修改关闭,如果你要加一个产品类C,你就要修改工厂类里面的生成产品的代码,在这里你就要增加if-else判断。对于这个问题,我们的工厂方法模式就可以解决这个问题。
接下来是工厂方法模式
产品类中增加了ProductC(其他产品类的代码是可以重用上面的,只要把包名更改了就行)。
声明工厂接口
产生ProductA的FactoryA
产生ProductB的FactoryB
产生ProductC的FactoryC
客户端
控制台输出结果:
工厂方法模式中我们把生成产品类的时间延迟,就是通过对应的工厂类来生成对应的产品类,在这里我们就可以实现“开发-封闭”原则,无论加多少产品类,我们都不用修改原来类中的代码,而是通过增加工厂类来实现。但是这还是有缺点的,如果产品类过多,我们就要生成很多的工厂类。假如我们要实现的产品接口不止一个,也就是有多个产品接口,不同产品接口有对应的产品族。什么是产品族呢?简单的理解就是,不同牌子产的车里面会有跑车类型,家庭类型,商用类型等的车,不同牌子的车的跑车类型的车可以组成一个产品族。对于这种情况我们可以采用抽象工厂模式。
最后是抽象工厂模式,在这里我们为不同产品附加上对应的礼物,就是说ProductA中会有GiftA。
增加的Gift接口
GiftA类
GiftB类
Factory接口
生成ProductA和GiftA的FactoryA
生成ProductB和GiftB的FactoryB
客户端
控制台输出结果:
抽象工厂模式中我们可以定义实现不止一个接口,一个工厂也可以生成不止一个产品类,抽象工厂模式较好的实现了“开放-封闭”原则,是三个模式中较为抽象,并具一般性的模式。我们在使用中要注意使用抽象工厂模式的条件。
首先是简单工厂模式,这里以工厂生产产品为例。
产品类的共同接口
package factory; /** * * @author CIACs * */ public interface Product { //声明类所需继承的共同接口,也可以是抽象类 }
产品类A
package factory; /** * * @author CIACs * */ public class ProductA implements Product { public ProductA() { System.out.println("ProductA"); } }
产品类B
package factory; /** * * @author CIACs * */ public class ProductB implements Product { public ProductB() { System.out.println("ProductB"); } }
工厂类
package factory; /** * * @author CIACs * */ public class Factory { //可以在工厂类中添加任何你所需要的逻辑 public static Product create(String str) { //生成ProductA if(str.equalsIgnoreCase("ProductA")) { return new ProductA(); } else //生成ProductB if(str.equalsIgnoreCase("ProductB")) { return new ProductB(); } return null; } }
客户端
package factory; /** * * @author CIACs * */ public class Client { public static void main(String[] args) { //调用Factory的静态方法生成所要的类 Factory.create("productA"); Factory.create("ProductB"); } }
控制台输出结果:
简单工厂模式实现了生成产品类的代码跟客户端代码分离,在工厂类中你可以添加所需的生成产品的逻辑代码,但是问题来了,优秀的java代码是符合“开放-封闭”原则的,也就是说对扩展开发,对修改关闭,如果你要加一个产品类C,你就要修改工厂类里面的生成产品的代码,在这里你就要增加if-else判断。对于这个问题,我们的工厂方法模式就可以解决这个问题。
接下来是工厂方法模式
产品类中增加了ProductC(其他产品类的代码是可以重用上面的,只要把包名更改了就行)。
package factoryMehtod; /** * * @author CIACs * */ public class ProductC implements Product { public ProductC() { System.out.println("productC"); } }
声明工厂接口
package factoryMehtod; /** * * @author CIACs * */ public interface Factory { //声明产生产品类的方法 public Product createProduct(); }
产生ProductA的FactoryA
package factoryMehtod; /** * * @author CIACs * */ public class FactoryA implements Factory { //实现工厂类的方法生成产品类A public Product createProduct() { return new ProductA(); } }
产生ProductB的FactoryB
package factoryMehtod; /** * * @author CIACs * */ public class FactoryB implements Factory { //实现工厂类的方法生成产品类B public Product createProduct() { return new ProductB(); } }
产生ProductC的FactoryC
package factoryMehtod; /** * * @author CIACs * */ public class FactoryC implements Factory { //实现工厂类的方法生成产品类C public Product createProduct() { return new ProductC(); } }
客户端
package factoryMehtod; /** * * @author CIACs * */ public class Client { public static void main(String[] args) { Factory factory; factory = new FactoryA(); factory.createProduct(); factory = new FactoryB(); factory.createProduct(); factory = new FactoryC(); factory.createProduct(); } }
控制台输出结果:
工厂方法模式中我们把生成产品类的时间延迟,就是通过对应的工厂类来生成对应的产品类,在这里我们就可以实现“开发-封闭”原则,无论加多少产品类,我们都不用修改原来类中的代码,而是通过增加工厂类来实现。但是这还是有缺点的,如果产品类过多,我们就要生成很多的工厂类。假如我们要实现的产品接口不止一个,也就是有多个产品接口,不同产品接口有对应的产品族。什么是产品族呢?简单的理解就是,不同牌子产的车里面会有跑车类型,家庭类型,商用类型等的车,不同牌子的车的跑车类型的车可以组成一个产品族。对于这种情况我们可以采用抽象工厂模式。
最后是抽象工厂模式,在这里我们为不同产品附加上对应的礼物,就是说ProductA中会有GiftA。
增加的Gift接口
package abstractFactory; /** * * @author CIACs * */ public interface Gift { //声明产品赠品的接口,当然也可以是抽象类,同样为了简单就不声明方法了 }
GiftA类
package abstractFactory; /** * * @author CIACs * */ public class GiftA implements Gift { public GiftA() { System.out.println("GiftA"); } }
GiftB类
package abstractFactory; /** * * @author CIACs * */ public class GiftB implements Gift { public GiftB() { System.out.println("GiftB"); } }
Factory接口
package abstractFactory; /** * * @author CIACs *声明Product类工厂和Gift类工厂的工同工厂接口 */ public interface Factory { public Product createProduct(); public Gift createGift(); }
生成ProductA和GiftA的FactoryA
package abstractFactory; /** * * @author CIACs *FactoryA可以生成ProductA和GiftA */ public class FactoryA implements Factory { @Override public Product createProduct() { return new ProductA(); } @Override public Gift createGift() { return new GiftA(); } }
生成ProductB和GiftB的FactoryB
package abstractFactory; /** * * @author CIACs *FactoryB可以生成ProductB和GiftB */ public class FactoryB implements Factory { @Override public Product createProduct() { return new ProductB(); } @Override public Gift createGift() { return new GiftB(); } }
客户端
package abstractFactory; /** * * @author CIACs * */ public class Client { public static void main(String[] args) { Factory factory; factory = new FactoryA(); factory.createProduct(); factory.createGift(); factory = new FactoryB(); factory.createProduct(); factory.createGift(); } }
控制台输出结果:
抽象工厂模式中我们可以定义实现不止一个接口,一个工厂也可以生成不止一个产品类,抽象工厂模式较好的实现了“开放-封闭”原则,是三个模式中较为抽象,并具一般性的模式。我们在使用中要注意使用抽象工厂模式的条件。
相关文章推荐
- 结合实例分析简单工厂模式&工厂方法模式&抽象工厂模式的区别
- 结合PXA270 Bootloader实例详细分析ARM映象文件
- php和数据库结合的一个 简单的web实例 代码分析 (php初学者)
- SlidingMenu官方实例分析7——SlidingContent和SlidingTitleBar区别
- ORACLE实例恢复过程详细分析--使用dump、BBED等多种工具结合分析
- ORACLE实例恢复过程详细分析--使用dump、BBED等多种工具结合分析
- 结合PXA270 Bootloader实例详细分析ARM映象文件
- C#中类与结构的区别实例分析
- php class中public,private,protected的区别以及实例分析
- asp.net 中静态方法和动态方法调用的区别实例分析
- 实例分析java中重载与重写的区别
- php和数据库结合的一个简单的web实例 代码分析 (php初学者)
- 设计模式解读之 简单工厂模式&工厂方法模式&抽象工厂模式(1)
- 关键字Ref和Out本质区别实例分析
- row_number()、rank()、dense_rank()这三个分析函数的区别实例
- 结合PXA270 Bootloader实例详细分析ARM映象文件
- 实例分析varchar和nvarchar的区别--【叶子】
- 设计模式解读之 简单工厂模式&工厂方法模式&抽象工厂模式(3)
- php class中public,private,protected的区别以及实例分析
- 用实例分析使用动态库DLL与使用静态库SLL的区别