之前写过一篇关于工厂模式(Factory Pattern)的随笔,里面分析了简单工厂模式,但对于工厂方法和抽象工厂的分析较为简略。这里重新分析分析三者的区别,工厂模式是java设计模式中比较简单的一个设计模式,但很多地方都用到了工厂模式,(如解析xml中,jdbc连接数据库等)利用好工厂模式对程序的设计很有用处。工厂模式在一些设计模式的书中分为简单工厂模式,工厂方法模式和抽象工厂模式三类。也有把工厂方法模式划分到抽象工厂模式的,认为工厂方法是抽象工厂模式的特例的一种,就是只有一个要实现的产品接口。下面结合例子分析三者的区别。

  首先是简单工厂模式,这里以工厂生产产品为例。

产品类的共同接口

  1. package factory;
  2. /**
  3. *
  4. * @author CIACs
  5. *
  6. */
  7. public interface Product {
  8. //声明类所需继承的共同接口,也可以是抽象类
  9. }

产品类A

  1. package factory;
  2. /**
  3. *
  4. * @author CIACs
  5. *
  6. */
  7. public class ProductA implements Product {
  8. public ProductA() {
  9. System.out.println("ProductA");
  10. }
  11. }

产品类B

  1. package factory;
  2. /**
  3. *
  4. * @author CIACs
  5. *
  6. */
  7. public class ProductB implements Product {
  8. public ProductB() {
  9. System.out.println("ProductB");
  10. }
  11. }

工厂类

  1. package factory;
  2. /**
  3. *
  4. * @author CIACs
  5. *
  6. */
  7. public class Factory {
  8. //可以在工厂类中添加任何你所需要的逻辑
  9. public static Product create(String str)
  10. {
  11. //生成ProductA
  12. if(str.equalsIgnoreCase("ProductA"))
  13. {
  14. return new ProductA();
  15. }
  16. else
  17. //生成ProductB
  18. if(str.equalsIgnoreCase("ProductB"))
  19. {
  20. return new ProductB();
  21. }
  22. return null;
  23. }
  24.  
  25. }

客户端

  1. package factory;
  2. /**
  3. *
  4. * @author CIACs
  5. *
  6. */
  7. public class Client {
  8. public static void main(String[] args) {
  9. //调用Factory的静态方法生成所要的类
  10. Factory.create("productA");
  11. Factory.create("ProductB");
  12. }
  13. }

控制台输出结果:

  简单工厂模式实现了生成产品类的代码跟客户端代码分离,在工厂类中你可以添加所需的生成产品的逻辑代码,但是问题来了,优秀的java代码是符合“开放-封闭”原则的,也就是说对扩展开发,对修改关闭,如果你要加一个产品类C,你就要修改工厂类里面的生成产品的代码,在这里你就要增加if-else判断。对于这个问题,我们的工厂方法模式就可以解决这个问题。

  接下来是工厂方法模式

产品类中增加了ProductC(其他产品类的代码是可以重用上面的,只要把包名更改了就行)。

  1. package factoryMehtod;
  2. /**
  3. *
  4. * @author CIACs
  5. *
  6. */
  7.  
  8. public class ProductC implements Product {
  9. public ProductC() {
  10. System.out.println("productC");
  11. }
  12. }

声明工厂接口

  1. package factoryMehtod;
  2. /**
  3. *
  4. * @author CIACs
  5. *
  6. */
  7. public interface Factory {
  8. //声明产生产品类的方法
  9. public Product createProduct();
  10. }

产生ProductA的FactoryA

  1. package factoryMehtod;
  2. /**
  3. *
  4. * @author CIACs
  5. *
  6. */
  7. public class FactoryA implements Factory {
  8. //实现工厂类的方法生成产品类A
  9. public Product createProduct()
  10. {
  11. return new ProductA();
  12. }
  13.  
  14. }

产生ProductB的FactoryB

  1. package factoryMehtod;
  2. /**
  3. *
  4. * @author CIACs
  5. *
  6. */
  7. public class FactoryB implements Factory {
  8. //实现工厂类的方法生成产品类B
  9. public Product createProduct()
  10. {
  11. return new ProductB();
  12. }
  13. }

产生ProductC的FactoryC

  1. package factoryMehtod;
  2. /**
  3. *
  4. * @author CIACs
  5. *
  6. */
  7. public class FactoryC implements Factory {
  8. //实现工厂类的方法生成产品类C
  9. public Product createProduct()
  10. {
  11. return new ProductC();
  12. }
  13. }

客户端

  1. package factoryMehtod;
  2. /**
  3. *
  4. * @author CIACs
  5. *
  6. */
  7. public class Client {
  8. public static void main(String[] args) {
  9. Factory factory;
  10. factory = new FactoryA();
  11. factory.createProduct();
  12. factory = new FactoryB();
  13. factory.createProduct();
  14. factory = new FactoryC();
  15. factory.createProduct();
  16. }
  17. }

控制台输出结果:

  工厂方法模式中我们把生成产品类的时间延迟,就是通过对应的工厂类来生成对应的产品类,在这里我们就可以实现“开发-封闭”原则,无论加多少产品类,我们都不用修改原来类中的代码,而是通过增加工厂类来实现。但是这还是有缺点的,如果产品类过多,我们就要生成很多的工厂类。假如我们要实现的产品接口不止一个,也就是有多个产品接口,不同产品接口有对应的产品族。什么是产品族呢?简单的理解就是,不同牌子产的车里面会有跑车类型,家庭类型,商用类型等的车,不同牌子的车的跑车类型的车可以组成一个产品族。对于这种情况我们可以采用抽象工厂模式。

   最后是抽象工厂模式,在这里我们为不同产品附加上对应的礼物,就是说ProductA中会有GiftA。

增加的Gift接口

  1. package abstractFactory;
  2. /**
  3. *
  4. * @author CIACs
  5. *
  6. */
  7. public interface Gift {
  8. //声明产品赠品的接口,当然也可以是抽象类,同样为了简单就不声明方法了
  9. }

GiftA类

  1. package abstractFactory;
  2. /**
  3. *
  4. * @author CIACs
  5. *
  6. */
  7. public class GiftA implements Gift {
  8. public GiftA()
  9. {
  10. System.out.println("GiftA");
  11. }
  12. }

GiftB类

  1. package abstractFactory;
  2. /**
  3. *
  4. * @author CIACs
  5. *
  6. */
  7. public class GiftB implements Gift {
  8. public GiftB()
  9. {
  10. System.out.println("GiftB");
  11. }
  12. }

Factory接口

  1. package abstractFactory;
  2. /**
  3. *
  4. * @author CIACs
  5. *声明Product类工厂和Gift类工厂的工同工厂接口
  6. */
  7. public interface Factory {
  8. public Product createProduct();
  9. public Gift createGift();
  10.  
  11. }

生成ProductA和GiftA的FactoryA

  1. package abstractFactory;
  2. /**
  3. *
  4. * @author CIACs
  5. *FactoryA可以生成ProductA和GiftA
  6. */
  7. public class FactoryA implements Factory {
  8. @Override
  9. public Product createProduct()
  10. {
  11. return new ProductA();
  12. }
  13. @Override
  14. public Gift createGift()
  15. {
  16. return new GiftA();
  17. }
  18. }

生成ProductB和GiftB的FactoryB

  1. package abstractFactory;
  2. /**
  3. *
  4. * @author CIACs
  5. *FactoryB可以生成ProductB和GiftB
  6. */
  7. public class FactoryB implements Factory {
  8. @Override
  9. public Product createProduct() {
  10. return new ProductB();
  11. }
  12. @Override
  13. public Gift createGift() {
  14. return new GiftB();
  15. }
  16.  
  17. }

客户端

  1. package abstractFactory;
  2. /**
  3. *
  4. * @author CIACs
  5. *
  6. */
  7. public class Client {
  8. public static void main(String[] args) {
  9. Factory factory;
  10. factory = new FactoryA();
  11. factory.createProduct();
  12. factory.createGift();
  13. factory = new FactoryB();
  14. factory.createProduct();
  15. factory.createGift();
  16. }
  17. }

控制台输出结果:

  抽象工厂模式中我们可以定义实现不止一个接口,一个工厂也可以生成不止一个产品类,抽象工厂模式较好的实现了“开放-封闭”原则,是三个模式中较为抽象,并具一般性的模式。我们在使用中要注意使用抽象工厂模式的条件。

结合实例分析简单工厂模式&工厂方法模式&抽象工厂模式的区别的更多相关文章

  1. Java设计模式---工厂模式(简单工厂、工厂方法、抽象工厂)

    工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类.工厂模式的形态工厂模式主要用一下几种形态:1:简单工厂(Simple Factory).2:工厂方法(Factory M ...

  2. 设计模式(Python)-简单工厂,工厂方法和抽象工厂模式

    本系列文章是希望将软件项目中最常见的设计模式用通俗易懂的语言来讲解清楚,并通过Python来实现,每个设计模式都是围绕如下三个问题: 为什么?即为什么要使用这个设计模式,在使用这个模式之前存在什么样的 ...

  3. 设计模式3---工厂模式(Factory Pattern简单工厂、工厂方法、抽象工厂)

    工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类.工厂模式的形态工厂模式主要用一下几种形态:1:简单工厂(Simple Factory).2:工厂方法(Factory M ...

  4. Java设计模式之简单工厂、工厂方法和抽象工厂

    在前面的学习中(参见前面的博客),我们学到了很多OO原则: 封装变化 多用组合,少用继承 针对接口/超类编程,不针对实现编程 松耦合 开闭原则 让我们从一个简单的类开始,看看如何将之改造成符合OO原则 ...

  5. 简单工厂 VS 工厂方法 VS 抽象工厂

    说到设计模式.自然少不了简单工厂模式.工厂方法和抽象工厂这三姐妹. 它们之间可谓是各有所长,术业专攻啊!这篇博客来简单的梳理一下三者之间的关系. 那么工厂又是什么意思呢?结合三者的特点,我觉得能够这样 ...

  6. c# 设计模式 之:简单工厂、工厂方法、抽象工厂之小结、区别

    很多时候,我发现这三种设计模式难以区分,常常会张冠李戴闹了笑话.很有必要深入总结一下三种设计模式的特点.相同之处和不同之处. 1 本质 三个设计模式名字中都含有“工厂”二字,其含义是使用工厂(一个或一 ...

  7. Java 工厂模式(一)— 抽象工厂(Abstract Factory)模式

    一.抽象工厂模式介绍: 1.什么是抽象工厂模式: 抽象工厂模式是所有形态的工厂模式中最为抽象和最具有一般性的一种形态,抽象工厂模式向客户端提供一个接口,使得客户端在不知道具体产品的情类型的情况下,创建 ...

  8. head first 设计模式笔记4-工厂模式(简单工厂、工厂方法、抽象工厂)

    1.简单工厂模式 Pizza public abstract class Pizza { abstract void prepare(); abstract void bake(); abstract ...

  9. 结合JDK源码看设计模式——简单工厂、工厂方法、抽象工厂

    三种工厂模式的详解: 简单工厂模式: 适用场景:工厂类负责创建的对象较少,客户端只关心传入工厂类的参数,对于如何创建对象的逻辑不关心 缺点:如果要新加产品,就需要修改工厂类的判断逻辑,违背软件设计中的 ...

随机推荐

  1. offsetWidth和clientWidth的介绍和区别

    1.offsetLeft 假设 obj 为某个 HTML 控件. obj.offsetTop 指 obj 间隔上方或上层控件的地位,整型,单位像素. obj.offsetLeft 指 obj 间隔左方 ...

  2. 特殊的反转单链表算法(C++)

    普通的单链表反转算法 大学的时候也做过好几次单链表的反转,记得当时都是用三个变量不断修改next的值然后实现反转. ListNode* reverseList(ListNode* head) { Li ...

  3. ZOJ 1914 Arctic Network (POJ 2349) MST

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1914 http://poj.org/problem?id=2349 题目大 ...

  4. Cocos2d-x滚动列表具体解释(CCScrollView的使用)

    今天要写一个滚动列表功能,类似以下这样.(图片资源都是自己从天天酷跑里面抠的,仅用于学习方便) 首先,这样一个列表就和iOS里面的UITableView没什么两样,当然,Android中肯定也存在类似 ...

  5. MySQL::SQL_MODE

    SQL_MODE可能是比较容易让开发人员和DBA忽略的一个变量,默认为空.SQL_MODE的设置其实是比较冒险的一种设置,因为在这种设置下可以允许一些非法操作,比如可以将NULL插入NOT NULL的 ...

  6. 局域网动态ip

    1. 局域网IP对网速没有任何影响.点“开始”“设置”进入“网络连接” 右击“本地连接”选择“属性”选中“Internet协议(TCP/IP)” 在下面的一些按钮中点“属性”,之后你可以设置局域网IP ...

  7. Java基础知识强化之IO流笔记53:IO流练习之 自定义类模拟BufferedReader的readLine()功能案例

    1. 用Reader模拟BufferedReader的readLine()功能:   readLine():一次读取一行,根据换行符判断是否结束,只返回内容,不返回换行符 2. 代码实现和思路分析: ...

  8. Android(java)学习笔记141:SQLiteDatabase的query方法参数分析

    public Cursor query (boolean distinct, String table, String[] columns, String selection, String[] se ...

  9. hdu 1587 Flowers

    Flowers Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  10. (转)CSS行高——line-height

    原文地址:http://www.cnblogs.com/dolphinX/p/3236686.html 初入前端的时候觉得CSS知道display.position.float就可以在布局上游刃有余了 ...