一、工厂方法模式的诞生

在读这篇文章之前,我先推荐大家读《设计模式之简单工厂模式(Simple Factory Pattern)》这篇文档。工厂方法模式是针对简单工厂模式中违反开闭原则的不足,而提出的改进方案。在简单工厂模式中,每增加一个新产品,就要修改工厂类的调度方法, 针对这个问题,工厂方法模式提出,工厂类提取成抽象的类或接口,定义调度规范。每新增一种产品,不仅要提供产品的实现类,还要提供调度这种产品的工厂类。这样,用户在用工厂方法模式时,需要哪个产品,就调用哪个产品的工厂类,即可获得。就不用只通过一个工厂类传参,去获得不同产品了。简单工厂模式改变的是产品参数,工厂方法模式改变的是工厂类型。

二、工厂方法模式的定义

工厂方法模式,又称工厂模式、多态工厂模式和虚拟构造器模式,通过定义工厂父类负责定义创建对象的公共接口,而子类则负责生成具体的对象。它的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。

通过第一部分的描述,这些官方的定义概念,是不是很好理解了呢?

三、工厂方法模式的角色

由上面的描述,我们可以得到工厂方法中,设计到的角色:

产品规范:和简单工厂模式的产品规范作用一样,定义规范;
产品实现:和简单工厂模式的产品实现一样,实现产品规范的方法;
抽象工厂:工厂方法模式新加的角色,用来制定调度产品的规范,供具体工厂类遵循;
工厂实现类:实现抽象工厂的规范,来调度不同的产品;不同的产品有不同的工厂实现来调度;
产品使用者:也就是业务程序员,工厂方法模式的使用,主要是选择不同的工厂实现类,来获取不同的产品;

四、工厂方法模式的实现

首先,还以家具为例,先定义产品规范,如下:

/*** 产品规范*/
public interface Furiniture {public void createFurniture();
}

然后,定义产品实现,如下:

/*** 产品实现类*/
public class Table implements Furiniture {@Overridepublic void createFurniture() {System.out.println("生产桌子");}
}
/*** 产品实现类*/
public class Chair implements Furiniture {@Overridepublic void createFurniture() {System.out.println("生产椅子");}
}

下面,我们要定义工厂,在这里,我们工厂也定义工厂抽象规范,让其他具体工厂类进行实现,如下:

/*** 工厂抽象类,定义调度产品的规范*/
public abstract class FurnitureFactory {public abstract void getFurniture();
}

然后定义工厂的实现类,因为现在有Table和Chair两个产品,所以需要两个工厂实现类,如下:

/*** 桌子产品的工厂类*/
public class TableFactory extends FurnitureFactory {@Overridepublic void getFurniture() {new Table().createFurniture();}
}
/*** 椅子工厂的工厂类*/
public class ChairFactory extends FurnitureFactory {@Overridepublic void getFurniture() {new Chair().createFurniture();}
}

调用者使用工厂方法模式,获得产品:

public class FactoryMethodUser {public static void main(String[] args) {//对于使用者而言,要选择具体的产品工厂类,进行产品的获得FurnitureFactory factory=new TableFactory();factory.getFurniture();}
}

当我们想增加产品时,如增加Sofa产品,需要增加产品实现类和产品工厂实现类。

五、工厂方法模式的优缺点

优点:

1.面向接口编程;

2.符合了开闭原则;

缺点

添加新产品时,除了增加新产品类外,还要提供与之对应的具体工厂类,系统类的个数将成对增加,在一定程度上增加了系统的复杂度。

六、与简单工厂模式的区别

工厂方法模式与简单工厂模式的区别主要是两方面:

1.对于产品提供方来说,不光要提供新的产品实现,还要提供产品的调度工厂实现类,需要提供两套规范的东西;

2.对于使用工厂模式的人来说,获得产品,不再是通过一个工厂,通过传入不同的产品参数来获得产品,而是直接选择相应的工厂实现类来获得产品即可。即简单工厂是一个工厂输出不同产品,工厂方法模式是不同工厂输出不同产品。

思考:工厂方法模式中,抽象工厂类,定义了统一规范,那产品是否有必要再定统一接口规范呢?

有必要。在定义抽象工厂的规范时,我们是要返回统一产品的。如何统一产品呢?就是定义产品规范。如果抽象工厂里不统一产品输出,那调用者调用起来,也就会产生五花八门的产品,这样明显是不合理的。

七、工厂方法模式在JDK中的应用

我们以Collection集合为例,说明工厂方法模式的应用。

Collection中用到的工厂方法模式,其实是工厂方法模式的变种,不是标准的工厂方法模式。我们来分析一下。

首先,找产品规范,是JDK定义的迭代器接口Iterable, 也就是实现产品,要继承Iterable接口,实现iterator()方法。核心代码如下图:

工厂抽象类:Collection接口,该抽象工厂定义了生产集合的规范。我们使用的ArrayList,HashSet,就是抽象工厂的实现类。

我们看Collection的源码可以发现,其继承了Iterable接口。也就是说,抽象工厂中,不光有工厂的规范,还有产品的规范。也就是说,在Collection中,将工厂规范和产品规范合二为一了。

那么我们可以猜想,工厂的实现类,和产品的实现类,也合二为一了。那么进一步推想,工厂类其实就是产品实现类了,那我们还用写调度方法吗,肯定不需要。我们只需要调用产品的方法,即可。

这样设计,就省去了工厂类调度产品,再通过产品调用产品方法的逻辑。直接通过工厂类,调用产品的方法。

我们看ArrayList的源码,其实现思路也是按上面的分析来实现的。

首先,ArrayList中无需写调度方法了,我们直接找其产品方法,iterator()方法。

由源代码可以看出,产品规范实现返回了Itr对象。来实现接口规范。那我们在调用时,直接通过ArrayList对象的iterator()就可以使用该产品了。

Collection实现工厂方法模式比较隐蔽,不容易被人发现。

设计模式之工厂方法模式(Factory Method Pattern)相关推荐

  1. 【设计模式】工厂方法模式 Factory Method Pattern

    在简单工厂模式中产品的创建统一在工厂类的静态工厂方法中创建,体现了面形对象的封装性,客户程序不需要知道产品产生的细节,也体现了面向对象的单一职责原则(SRP),这样在产品很少的情况下使用起来还是很方便 ...

  2. 设计模式之六:工厂方法模式(Factory method Pattern)

    工厂方法(Factory Method)模式就是定义一个创建对象的工厂接口,将实际创建工作推迟到子类当中. 核心工厂类不再负责具体产品的创建,仅提供了具体工厂子类必须实现的接口,这样核心类成为一个抽象 ...

  3. 极速理解设计模式系列:9.工厂方法模式(Factory Method Pattern)

    五个角色:产品角色(Product).真实产品角色(ConcreteProduct).工厂角色(Creator).真实工厂角色(ConcreteCreator).客户端(Client) 产品角色(Pr ...

  4. 设计模式之工厂方法模式---factory method

    模式的介绍 模式的定义 Define an interface for creating an object,but let subclassed decide which class to inst ...

  5. 设计模式之工厂方法模式(Factory Method)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式包括:1.FactoryMethod(工厂方法模式):2.Abstract Factory(抽象工厂模式):3.Sin ...

  6. C++实现工厂方法模式Factory Method Pattern

    设计原则6:要依赖抽象,不要依赖具体类.(又称依赖倒置原则Dependency Inversion Principle) 不能让高层组件依赖低层组件,而且,不管高层组件或低层组件,两者都应该依赖于抽象 ...

  7. 设计模式题目-工厂方法模式(Factory Method)

    设计一个程序来读取多种不同存储格式的图片,针对每一种图片格式都设计一个图片读取器(ImageReader),如GIF格式图片读取器(GifReader)用于读取GIF格式的图片,JPEG格式图片读取器 ...

  8. 工厂方法模式(Factory Method)简介

    工厂方法模式 名字 跟已经介绍的 简单工厂模式很类似. 实际上它们的模型也是十分相似的. 我们先看看工厂模式的定义. 一. 工厂方法(Factory Method)模式定义 教材上是这样写的: 工厂方 ...

  9. 浅谈C++设计模式之工厂方法(Factory Method)

    为什么要用设计模式?根本原因是为了代码复用,增加可维护性. 面向对象设计坚持的原则:开闭原则(Open Closed Principle,OCP).里氏代换原则(Liskov Substitution ...

最新文章

  1. 一位39岁程序员的困惑:知道得越多编程越慢怎么办?
  2. mockito_Mockito:为什么您仍然应该欣赏InjectMocks注释
  3. Linux编程网络通信
  4. 合并bin文件-----带boot发布版本比较好用的bat(便捷版)
  5. ueditor如何设置上传图片的高度宽度_怎么设置天猫主图
  6. iOS 10 的坑:新机首次安装 app,请求网络权限“是否允许使用数据”(转)
  7. 入门干货:Python操作Word文件经验分享
  8. SQuAD2.0来了!新增5万人工撰写问题,且不一定有答案 | ACL最佳短论文
  9. 字典 选取前100_100道 Python 经典练习题004
  10. 第四周任务:wordCountPro
  11. 内存瓶颈和计算负载问题一举突破?韩松团队提出MUCNetV2:解锁MCU端新纪录!...
  12. 图的更多相关算法-2(最小生成树)
  13. 宏基aspire拆机触摸_(图) 宏基 Acer 4741G 完全拆解
  14. PDF不小心删掉了怎么恢复?4个方法隔壁家老王已经恢复了
  15. 数据结构—串-基本知识点(第五章)
  16. 现在到底要不要学Python
  17. Leadtools Document教程:如何高效将数千个 PDF 文件拆分并转换为单页图像
  18. Swift+Ubuntu on Mac
  19. trans【Total3DUnderstanding】论文翻译+解读学习 2020.10.14
  20. kaggle数分项目 | netfix影视内容分析

热门文章

  1. 喜报东方证券携手博睿数据荣获《金融电子化》2021科技赋能金融业务突出贡献奖
  2. 现代软件工程 第一章 【概论】第2题——孙雪莹
  3. 便利店行业全面爆发,“酷铺+掌合”先于京东完成百万门店布局
  4. 有关prototype的理解
  5. linux renice命令,Linux操作系统的renice命令详解
  6. chatgpt赋能Python-python3_7如何安装matplotlib
  7. 【蓝桥杯选拔赛真题53】Scratch破解保险柜 少儿编程scratch图形化编程 蓝桥杯选拔赛真题讲解
  8. 一个真实而又令人震撼的故事
  9. 第一次运行TestNG测试类时报Cannot find class in classpath
  10. 黑科技抢先尝 - Windows全新终端初体验(附无需编译就能安装的Preview版本及代码Build全过程)...