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

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

前言

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

一 为什么需要工厂

系统中总是需要创建对象的,一般使用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. Java基础知识篇02——Java基本语法

    一.数据类型 定义: 就是用了保存数据的一个类型,一种数据类型,只能保存该类型数据值 作用: 只有了解数据类型,才能选择合适的类型存放数据,才能更好的利用计算机硬件资源(内存和硬盘等). 不同的数据类 ...

  2. [pyplot]在同一画面上绘制不同大小的多个图像

    一.背景 做计算机应用数学作业时要求使用matplotlib库在同一张图上绘制两个图像,但是这两个图像的大小不同,百度之后发现大部分只是转载的同一篇博客,而且只能实现部分子图比例排版,并不能随意设置各 ...

  3. 说JS作用域,就不得不说说自执行函数

    一个兜兜转转,从"北深"回到三线城市的小码农,热爱生活,热爱技术,在这里和大家分享一个技术人员的点点滴滴.欢迎大家关注我的微信公众号:果冻想 前言 不得不吐槽,学个JS,这个概念也 ...

  4. 3DCAT首届行业生态交流会|瑞云科技技术总监赵志杰:实时渲染助力元宇宙应用触手可及

    2021年12月17日下午,由深圳市瑞云科技有限公司主办,深圳市虚拟现实产业联合会协办的 云XR如何赋能元宇宙--3DCAT实时云渲染首届行业生态合作交流会 圆满落幕.此次活动围绕 "云XR ...

  5. Asp-Net-Core开发笔记:实现动态审计日志功能

    前言 最近一直在写 Go 和 Python ,好久没写 C# ,重新回来写 C# 代码时竟有一种亲切感~ 说回正题. 在当今这个数字化迅速发展的时代,每一个操作都可能对业务产生深远的影响,无论是对数据 ...

  6. C# OpenCvSharp-HoughCircles(霍夫圆检测) 简单计数

    效果 项目 代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.D ...

  7. KingbaseES V8R6 中unlogged表

    前言 KingbaseESV8R6有一种表称为unlogged,在该表新建的索引也属于unlogged.和普通表的区别是,对该表进行DML操作时候不将该表的变更记录变更写入到wal文件中.在数据库异常 ...

  8. Make It Equal 题解

    Problem Link 简要题意 翻译很清楚. 思路 提供一种简单直接的思路. 可以发现最多会操作 \(n\) 次. 那么就可以每次直接枚举切的高度 \(h\),检查更改是否超过 \(k\),之后暴 ...

  9. Sealos 开源初创公司 Trending 全球 TOP50,中国第二!

    今年,Runa Capital (鲁纳资本) 评选出了 2023 年增长最快的 50 家开源创业公司,Sealos 压轴登场,总共有两家中国公司上榜,Sealos 排名第二. Runa Capital ...

  10. #线段树合并、树上启发式合并#CF600E Lomsat gelral

    题目 一棵树有\(n\)个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和 分析1 线段树合并,记录\(w,sum\)分别表示编号和以及颜色和,当颜色和相同时两个编号 ...