重温设计模式之 Factory

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

image.png

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

前言

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

一 为什么需要工厂

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

二 工厂模式中的角色划分

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

三 对工厂的基本认知

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

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

四 工厂模式的简单划分

1 简单工厂模式

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

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

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

2 工厂方法模式

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

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

3 抽象工厂模式

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

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

五 简单工厂模式详解

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

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

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

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

image.png

1 DEMO:抽象产品接口

image.png

2 DEMO:具体产品实现

image.png

3 DEMO:具体产品实现

image.png

4 DEMO:简单工厂类

image.png

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

image.png

六 工厂方法模式详解

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

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

image.png

1 DEMO:产品抽象接口

image.png

2 DEMO:具体产品实现

image.png

3 DEMO:具体产品实现

image.png

4 DEMO:抽象工厂

image.png

5 DEMO:具体工厂实现

image.png

6 DEMO:具体工厂实现

image.png

7 DEMO:测试类——上下文

image.png

七 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 抽象工厂模式角色

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

image.png

2 DEMO:抽象产品

image.png

3 DEMO:具体产品

image.png

image.png

4 DEMO:抽象工厂

image.png

5 DEMO:具体工厂

image.png

image.png

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

image.png

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

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

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

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

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

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

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

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

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

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

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

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

1 抽象工厂的优点

分离了接口和实现

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

使切换产品族变得容易

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

2 抽象工厂的缺点

不太容易扩展新的产品

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

十四 最佳实践

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/513013.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

云端上的字节,引擎火力全开

作者 | 贾凯强出品 | CSDN云计算(ID:CSDNcloud)十二月,在产业最震撼的一条消息莫过于字节跳动旗下火山引擎终于出云产品了。字节跳动的业务早已跑在云上,这早已是行业公开的信息。可是这朵云究竟有多大呢?在…

收件服务器信息,收件服务器配置信息

收件服务器配置信息 内容精选换一换SAP HANA运行在SAP HANA云服务器上。需要根据部署场景,创建一台或多台HANA云服务器,用于部署SAP HANA软件。请参见方案和数据规划相关章节,确定HANA云服务器数量及相关规划信息。在集群场景下创建多台HANA云…

Nacos 2.0 升级前后性能对比压测

简介: Nacos 2.0 通过升级通信协议和框架、数据模型的方式将性能提升了约 10 倍,解决继 Nacos 1.0 发布逐步暴露的性能问题。本文通过压测 Nacos 1.0,Nacos 1.0 升级 Nacos 2.0 过程中,Nacos 2.0 进行全面性能对比,直观…

深入浅出讲解MSE Nacos 2.0新特性

简介: 随着云原生时代的到来,微服务已经成为应用架构的主流,Nacos也凭借简单易用、稳定可靠、性能卓越的核心竞争力成为国内微服务领域首选的注册中心和配置中心;Nacos2.0更是把性能做到极致,让业务快速发展的用户再也…

交换机是如何对数据包打标签去标签的_条形码软件如何在标签纸上套打可变条码...

在制作商品标签时,通常会遇到标签纸上已经有部分内容,需要我再添加打印一些对应的信息(如下图),那么这种情况下,如何比较简单的在合适位置上打印可变条码呢,下面我们就来详细看一下在中琅条形码软件中套打可变条码的操…

学不动也要学!ViewPager2 新特性

作者 | tech-bus.丹卿来源 | 程序员八十前 言浏览Android开发者官网的时候,发现Google竟然曾经悄悄推出过一个新的控件:ViewPager2;从名字上看就知道是ViewPager的升级版本,看了下推出这个控件的时间,早在2019年2月7号Google就已经发布了&…

方舟手游服务器受人无限物资,方舟生存进化BUG无限刷物资方法 | 手游网游页游攻略大全...

发布时间:2015-10-23壳是铁房子必须的材料,今天小编为大家带来一天1000壳的方法,不过高收益伴随着高风险,大家一定要小心,来看这篇熔岩洞生存攻略以及刷壳方法把. 右下角坐标(75 85 ...标签:游戏攻略 游戏秘籍 方舟生存进化发布时间:2016-04-…

闲鱼如何保障交易链路质量

简介: 闲鱼交易质量自动化 背景 闲鱼作为一款垂直交易社区APP,拥有复杂多样的业务场景:涉及c2c、回收寄卖、租房租赁、见面交易、验货担保等,复杂多变的交易模式。比如验货流程:涉及39个状态机节点横跨10应用系统涉及…

DevOps发布策略简介

简介: DevOps追求更短的迭代周期、更高频的发布。但发布的次数越多,引入故障的可能性就越大。更多的故障将会降低服务的可用性,进而影响到客户体验。所以,为了保证服务质量,守好发布这个最后一道关,阿里逐步…

存储引擎 boltdb 的设计奥秘?

作者 | 奇伢来源 | 奇伢云存储etcd 的存储etcd v3 是使用的持久化存储来存储它的 kv 数据,etcd 存储的是非常核心的元数据信息,所以最重要的是稳定。使用的是 boltdb 。下面说道说道这个 boltdb 。boltdb 是什么?boltdb 是一个非常出名的存储…

提升你的职场竞争力——“低代码开发师”来了!

简介: 最近,钉钉发布了低代码开发师能力图谱,引发业界的广泛关注 。现在低代码开发师(初级)认证已经启动。 最近,钉钉发布了低代码开发师能力图谱,引发业界的广泛关注 。 所谓的低代码开发其实…

mapreduce复制连接的代码_我的 Hive 为什么跑不起来/跑得慢?看看是不是少了这几行代码?...

《饮食男女》开头说:“人生不能像做菜,把所有的料都准备好了才下锅。”但做大数据挖掘不一样,MapReduce 不同于人生,一定要把准备工作做好了,才能顺利运行后面的步骤。如果你的 HiveQL 代码没毛病,却一运行…

数字化转型的路上,手握一张地图,但路还得自己走

简介: 本文作者来自于中国人寿保险股份有限公司研发中心,对企业数字化转型、云原生实践有比较资深的经验。以下内容整理自作者对最新出版的《阿里云云原生架构实践》的读后感。 作者|肖晟 ​ 本文作者来自于中国人寿保险股份有限公司研发中…

tp 数据库查询排序_怎么进行数据库分库分表?

一,数据切分关系型数据库本身比较容易成为系统瓶颈,单机存储容量、连接数、处理能力都有限。当单表的数据量达到1000W或100G以后,由于查询维度较多,即使添加从库、优化索引,做很多操作时性能仍下降严重。此时就要考虑对…

流利说统一可观察性平台实践

简介: 流利说利用日志服务SLS构建统一可观察性平台最佳实践 在线教育行业现状 随着 90 年代互联网的引入,在线教育产品也依托于互联网诞生。随着互联网技术的发展,在线教育产品也开 始了出现新的模式。在线教育从最初单纯的文字形式&#xf…

“CSDN 2021年度IT技术影响力之星评选”正式开启报名!

2021年,数字化转型正磅礴兴起,大批传统企业正在拥抱数字化,云计算、大数据、AI、5G应用能力正在变成企业的核心竞争力;核心技术正在崛起,在操作系统、数据库,依靠开源的力量,众多开发者背后的行…

java log4j logback jcl_Java 日志二三事

前言Java 拥有功能和性能都非常强大的日志库,但另一方面,Java 日志库依赖看起来丰富的让人眼花缭乱。相信大家或多或少都有这样的疑问,Log4j,SLF4J,Logback,Log4j2 这些日志框架我该如何选择?它…

一文了解EPaxos核心协议流程

简介: EPaxos(Egalitarian Paxos)作为工业界备受瞩目的下一代分布式一致性算法,具有广阔的应用前景。但纵观业内,至今仍未出现一个EPaxos的工程实现,甚至都没看到一篇能把EPaxos讲得通俗一点的文章。EPaxos…

低代码发展系列专访之五:低代码的最大价值点是“技术平民化”吗?

话题:低代码专访编辑 | LLBin前言:2019年开始,低代码爆火。有人认为它是第四代编程语言,有人认为它是开发模式的颠覆,也有人认为是企业管理模式的变革……有很多声音,社区讨论很热烈。CSDN随后展开低代码平…

梦幻跨服购买需要登录服务器未响应,梦幻西游8月4日定期维护公告:跨服购买限制放宽...

核心提示:法宝”系统新增“多套法宝切换”功能。亲爱的玩家朋友:为保证服务器的运行稳定和服务质量,《梦幻西游2》所有服务器将于2015年8月4日上午8:00停机,进行每周例行的维护工作。预计维护时间为上午8:00~9:45。如果…