简介: 创建型模式的核心干将,工厂、简单工厂、抽象工厂,还记得清么,一文回顾和对比下。

作者 | 弥高
来源 | 阿里技术公众号

前言

创建型模式的核心干将,工厂、简单工厂、抽象工厂,还记得清么,一文回顾和对比下。

一 为什么需要工厂

系统中总是需要创建对象的,一般使用new()来创建对象。创建对象可以是简单的new(),也可以有复杂的加工逻辑,如果在主程序中创建对象,那么就是将主干逻辑和创建对象的非主干逻辑耦合在了一起,工厂模式要做的就是将非核心的对象创建逻辑与主干逻辑解耦,通过调用工厂的创建方法直接获取到一个对象。

二 工厂模式中的角色划分

  • 抽象产品角色(都有)
  • 具体产品角色(都有)
  • 抽象工厂角色(工厂方法模式和抽象工厂模式有)
  • 具体工厂角色(都有)
  • 上下文角色(都有)——调用工厂获取对象

三 对工厂的基本认知

工厂方法总是基于一定的入参,返回对应的产品对象,即工厂是用来生产产品的。

工厂方法可能根据不同条件创建不同的具体产品实体,因此工厂方法的返回类型是抽象产品类型。

四 工厂模式的简单划分

1 简单工厂模式

产品有抽象层,但是工厂没有抽象层,在一个工厂中根据传参创建相应的产品类型。

如果需要新增产品族(例如在A_cpu,B_cpu之外新增C_cpu),那么需要在工厂方法中进行逻辑修改,没有做到开闭原则——对扩展开放,对修改封闭。

简单工厂模式就是静态工厂模式,不属于GOF23中的模式,就是一个简单的封装,在静态工厂模式中,工厂方法是静态的,所以叫做静态工厂方法。

2 工厂方法模式

产品有抽象层,工厂也有抽象层,一个工厂对应一个产品(即一个工厂只能创建一个产品类别)。

如果新增产品,只需要新增工厂,不需要对原有工厂逻辑进行修改,符合开闭原则。

3 抽象工厂模式

产品有抽象层,工厂有抽象层,一个工厂对应多个产品(即一个工厂可以创建多个产品类别)。

用于解决有多有产品类别(芯片、主板、显卡)情况下,产品族(A产品族、B产品族)的切换替代问题。

五 简单工厂模式详解

简单工厂模式下,只有一个工厂类,工厂角色没有抽象层次。

使用这一个工厂生产出不同的产品实现,例如使用CpuFactory这一个产品类中会生产出ACpu、BCpu等具体的产品实现。

如果要新增产品实现,例如CCpu,需要修改该工厂方法的代码。

简单工厂模式中,决定生成哪个产品的逻辑在工厂内实现。

1 DEMO:抽象产品接口

2 DEMO:具体产品实现

3 DEMO:具体产品实现

4 DEMO:简单工厂类

5 DEMO:测试类——调用工厂创建对象的客户端代码

六 工厂方法模式详解

工厂方法模式中,对工厂也进行了抽象,一个抽象工厂还是对应一个产品类别,例如CpuFacroy接口对应生产Cpu产品,但是具体生产的时候,将具体的产品实现交给每个具体的工厂实现去生产;即在CpuFactory接口下,有ACpuFactory和BCpuFactory,分别来生产ACpu和BCpu这2中具体的产品。

工厂方法模式中具体的工厂负责创建具体的产品,工厂内部的逻辑只负责创建对应对象,决定生成什么产品的逻辑在外部客户端,客户端通过选择使用具体工厂,间接决定了生成什么产品。

1 DEMO:产品抽象接口

2 DEMO:具体产品实现

3 DEMO:具体产品实现

4 DEMO:抽象工厂

5 DEMO:具体工厂实现

6 DEMO:具体工厂实现

7 DEMO:测试类——上下文

七 THINK:简单工厂&工厂方法模式的区别

简单工厂模式中工厂类没有抽象层,而工厂方法模式中工厂类有抽象工厂。

决定生成具体什么产品的逻辑在哪里实现?

  • 简单工厂模式中,客户端决定传递什么类型的参数,在工厂中根据不同的参数决定创建不同的对象,即工厂内部有决策创建产品的逻辑。
  • 工厂方法模式中,具体工厂内部很纯净,什么类型的工厂就负责创建对应的产品,决策的逻辑全部在客户端中实现。

当需要新增产品实现时,简单工厂模式需要修改工厂逻辑,工厂方法模式只需要新增具体工厂实现,不需要修改工厂内部逻辑。

八 THINK:工厂方法 & 抽象工厂模式的区别

1 工厂方法模式

工厂方法模式用于解决一个产品(Cpu),有多个产品族(ACpu,BCpu)的情况,以抽象产品作为工厂,例如CpuFactory,每个产品族对应一个具体工厂,例如ACpuFactory,BCpuFactory,即工厂方法模式以产品维度来建厂。

工厂方式模式中,多一个新的抽象产品的话需要新建立一个抽象工厂,例如新建MainboardFactory等。即如果需要新增产品线(XianKa),则需要新增抽象工厂(XianKaFactory);如果需要在某个产品(Cpu)下新增具体产品,则需要新增具体工厂(CCpuFactory)。

工厂方法模式中以抽象产品维度建厂,每个抽象产品一个工厂,当产品族(A,B,C……)增加的时候,需要为每个产品的抽象工厂新增具体工厂(CCpuFactory,CMainboardFactory,CXianKaFactory)。

2 抽象工厂模式

在工厂方法模式下,当产品线(品类:cpu/主板/显卡)和产品族(A/B/C)水平扩展后,如果要新增产品族,那么需要在所有工厂下面新增新产品族的所有产品,即在cpu工厂、主板工厂、显卡工厂……都新增C的具体工厂,这样显然改动太大,此时就要考虑使用抽象工厂模式。

抽象工厂模式下,以产品族维度来建厂,一个厂里有多个创建方法,每个创建方法负责创建一个产品线,例如有A工厂、B工厂,每个工厂里面有创建cpu的方法、创建主板的方法、创建显卡的方法,当需要新增一个产品族的时候,只需要新增一个工厂,例如C工厂,在该工厂中创建各个产品即可。

3 总结

工厂方法模式和抽象工厂模式的最大区别是工厂方法模式针对的是一个产品等级结构,而抽象工厂模式针对的是多个产品等级结构。

九 抽象工厂模式详解

1 抽象工厂模式角色

  • 抽象产品
  • 具体产品
  • 抽象工厂:以产品族维度建工厂类,类中含有多个抽象方法,每个方法对应创建一个产品。
  • 具体工厂:具体工厂实现抽象工厂,并实现里面的所有产品创建方法,创建属于当前具体产品对象。
  • 环境类:持有抽象工厂,并可以在运行时注入具体工厂。

2 DEMO:抽象产品

3 DEMO:具体产品

4 DEMO:抽象工厂

5 DEMO:具体工厂

6 DEMO:测试类——类似程序上下文

十 THINK:工厂模式中的方法一定是静态的吗?

在简单工厂中,工厂方法没有对应的抽象,可以定义为静态的。

在工厂方法模式和抽象工厂模式中,工厂都有对应的抽象接口,而接口中的抽象方法不能定义为静态,所以工厂方法也不能是静态的。

十一 THINK:对于接口中static的理解

接口interface以及接口中的方法都是public abstract的。

接口中的方法都是抽象方法,没有方法体,因此也不允许使用static来修饰(static方法表示可以被类调用,接口因为没有功能体,所以没有人调用,所以不允许声明为static)。

但是从JDK8开始,接口中方法可以有static,此时的方法必须有方法体,即接口中可以含有非抽象的方法,和抽象类一样了,接口中非抽象的方法不需要被实现,抽象的方法必须要求子类实现。

十二 工厂模式 & 抽象工厂的使用场景

一个系统不应当依赖于产品类实例如何被创建、组合、表达的细节,这是所有工厂模式都要关注解决的问题。

当系统中的产品有多个产品族,虽然对于任何一个具体请求只属于其中一个产品族,但是对于系统而言,应当面向产品族设计,即使用抽象工厂模式。

当系统中有多个产品族,并且这个产品族中的产品通常是在一起使用,一起创建的,如果这种约束需要在系统设计中体现出来,那么应当使用抽象工厂模式(例如:不管是A产品族,还是B产品族中的芯片、主板、磁盘这些产品通常需要一起创建)。

十三 抽象工厂模式的优缺点

1 抽象工厂的优点

分离了接口和实现

客户端使用抽象工厂来创建需要的对象,而客户端根本就不知道具体的实现是谁,客户端只是面向产品的接口,也就是说客户端从具体的产品中实现了解耦。

使切换产品族变得容易

因为一个具体的工厂代表的是一个产品族,比如上面例子中的A系列到B系列只需要切换一下具体的工厂。

2 抽象工厂的缺点

不太容易扩展新的产品

如果需要给这个产品族添加一个新的产品,那么就需要修改抽象工厂,需要在抽象工厂中添加新产品创建方法,同时需要给所有的具体工厂增加接口。

十四 最佳实践

都使用抽象工厂模式,按照产品族维度来建立工厂,如果只有一个产品那么工厂中就一个方法,如果有多个产品就多个方法。

原文链接
本文为阿里云原创内容,未经允许不得转载。

重温设计模式之 Factory的更多相关文章

  1. 设计模式 工厂-Factory

    在开始笔记之前先推荐一个网站:http://design-patterns.readthedocs.org/zh_CN/latest/index.html 网站对每一个Pattern都有详尽的解说.并 ...

  2. [学习笔记]设计模式之Factory Method

    写在前面 为方便读者,本文已添加至索引: 设计模式 魔法手札索引 在上篇笔记Abstract Factory设计模式中,时の魔导士创建了一系列的FoodFactory,并教会了其中一名霍比特人theC ...

  3. 设计模式学习--Factory Method

    What Factory Method:定义一个创建对象的接口,让子类来决定实例化哪一个类.Factory Method使一个类的实例化延迟到其子类. Why Factory Method是一个比較基 ...

  4. 简单工厂设计模式(Simple Factory Design Pattern)

    [引言]最近在Youtub上面看到一个讲解.net设计模式的视频,其中作者的一个理解让我印象很深刻:所谓的设计模式其实就是运用面向对象编程的思想来解决平时代码中的紧耦合,低扩展的问题.另外一点比较有见 ...

  5. 设计模式之Factory

    设计模式总共有23种模式这仅仅是为了一个目的:解耦+解耦+解耦...(高内聚低耦合满足开闭原则) 介绍: Factory Pattern有3种当然是全部是creational pattern. 1.S ...

  6. 一天一个设计模式——Abstract Factory抽象工厂模式

    一.模式说明 前面学习了工厂方法(Factory Method)模式.在工厂方法模式中,在工厂方法模式中,父类决定如何生成实例,但并不决定所要生成的具体类,具体的处理交由子类来处理.这里学习的抽象工厂 ...

  7. 重温设计模式(三)——职责链模式(chain of responsibility)

    一. 写在前面的 这么多的设计模式,我觉得职责链是我第一次看上去最简单,可是回想起来却又最复杂的一个模式. 因此,这个文章我酝酿了很久,一直也没有胆量发出来,例子也是改了又改,可是仍然觉得不够合理.所 ...

  8. 设计模式 - Abstract Factory模式(abstract factory pattern) 详细说明

    Abstract Factory模式(abstract factory pattern) 详细说明 本文地址: http://blog.csdn.net/caroline_wendy/article/ ...

  9. 设计模式之Factory工厂模式的好处

    最最直观的好处就是吹牛逼,看着要比普通创建对象要屌 好看 一般情况下,我们创建对象使用的是new. Sample sample=new Sample(); 然而,实际情况会比这样复杂的多,比如说 Sa ...

  10. 设计模式之Factory模式 代码初见

    ObjectFactory就是通过Factory建造一个Object,比如说DBConnectionFactory就是专门建造DBConnection的工厂 BuilderFactory就是通过Fac ...

随机推荐

  1. 08.Java反射问题

    目录介绍 8.0.0.1 反射的原理是什么?有哪些途径获取到Class对象,Class类的含义和作用是什么?什么是class类? 8.0.0.2 有哪些方式可以提高反射效率?为何反射消耗性能?究竟是怎 ...

  2. 崩溃bug日志总结2

    目录介绍 1.1 java.lang.ClassNotFoundException类找不到异常 1.2 java.util.concurrent.TimeoutException连接超时崩溃 1.3 ...

  3. 记录--前端实现电子签名(web、移动端)通用

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前言 在现在的时代发展中,从以前的手写签名,逐渐衍生出了电子签名.电子签名和纸质手写签名一样具有法律效应.电子签名目前主要还是在需要个人确 ...

  4. 记录--uniapp map 制作一个简单的地图导航

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 先上效果 简易map 在图一的地图中可以看到 a点 连接 到 b点, 基本信息 以及 基本的控件(放大.缩小.回到某个指定的点),接下来我 ...

  5. 无人不识又无人不迷糊的this

    本文分享自华为云社区<3月阅读周·你不知道的JavaScript | 无人不识又无人不迷糊的this>,作者: 叶一一. 关于this this关键字是JavaScript中最复杂的机制之 ...

  6. 聊聊微信小程序的隐私协议开发

    为什么需要隐私协议? 小程序隐私授权弹窗FAQ官方:https://developers.weixin.qq.com/community/develop/doc/00000ebac5c3e042384 ...

  7. quartus之rom的IP测试

    quartus之rom的IP测试 1.rom的作用 rom,就是只读存储器,内部数据在下载电路时就已经确认,不能使用信号驱动更改,只能够读取,一般用于比较重要的配置数据.在quartus中,可以直接调 ...

  8. multisim中常见的显示器

    multisim中常见的显示器 1.实验原理 multisim中做实验仿真一般需要各种各样的仿真器来模拟实验结果.这里列举几种比较常见的显示器以便后面快速选择. 2.实验操作 (1)LED[二极管] ...

  9. KingabseES 表空间限额子句(QUOTA Clause)

    概述 在Oracle数据库中,DBA权限用户,可以为其他用户,创建对象,即使该用户没有任何权限.当DBA用户在该用户的表,插入数据时,提示 超出表空间的空间限额 .这就需要设置该用户的表空间的空间限额 ...

  10. 使用 shell 脚本自动申请进京证 (六环外)

    问题背景 外地车辆进入北京,需要办理<进京证>,不办理证件驶入后会被执法设备抓拍,一次罚 100 扣 1 分,目前唯一的线上办理通道是下载<北京交警>App,注册后添加车辆,就 ...