查看: 164|回复: 5

设计模式篇——工厂模式详解

[复制链接]

2

主题

6

帖子

11

积分

新手上路

Rank: 1

积分
11
发表于 2022-9-20 18:01:39 | 显示全部楼层 |阅读模式
神话故事——女娲造人

在介绍工厂模式之前,我们先来看一个女娲造人的神话故事。东汉《风俗通》记录了这样一则神话故事:“开天辟地,未有人民,女娲搏黄土做人”,说的就是女娲造人的故事。女娲是如何造人的呢?过程大概是这样的:首先,女娲采集黄土捏成人的形状,然后放到八卦炉中烧制,最后放到大地上生长。由于女娲是第一次做人,经验不足,对火候的把控不准确,柴火放多了,火太旺,七七四十九天之后,造好拿出来一看,人都被烤黑了,于是,黑种人就诞生了;然后女娲开始少放柴火,小火慢炖,又过了七七四十九天,拿出来一看,人还没烤熟呢,于是,白种人就诞生了;最后,女娲有经验了,把控好火的大小,就这样又过了七七四十九天,打开八卦炉一看,嗯,这次就对了,于是黄种人就诞生了。
那我们可以用程序来实现这个有意思的女娲造人功能吗?可以实现!接下来,我们就通过工厂模式来实现女娲造人这个功能。
工厂模式

工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。它是创建行模式。
工厂模式有三种:简单工厂模式、工厂方法模式和抽象工厂模式。接下来我们用这三种工厂模式分别实现女娲造人程序。
简单工厂模式

Java是面向对象的语言编程,要用程序实现女娲造人,我们要先确定好有哪些对象。经过分析,该过程涉及三个对象:女娲、八卦炉和三种肤色的人。女娲相当于调用方Client,八卦炉相当于生产人的工厂,三种肤色的人肯定都是人类,所以我们定义一个人类接口,让三种肤色的人实现这个接口。分析完毕,我们画出了如下的类图:



HumanFactory是一个创建人类的工厂(八卦炉),它有一个创建人类的方法 createHuman,具体创建什么肤色的人来根据方法的入参决定。它们的源码如下。
人类及其实现类代码如下:



工厂类代码:



一切准备就绪,女娲就可以开始造人了:



执行结果如下:



以上就是我们通过简单工厂模式实现的女娲造人的小程序,非常简单。
简单工厂模式的优缺点

简单工厂模式的优点:将对象的创建交给专门的工厂类负责,实现了对象的创建和对象的使用分离。
简单工厂模式的缺点:工厂类不够灵活,增加新的具体产品需要修改工厂类的判断逻辑代码,比如都看过X战警吧,里面的魔形女是绿皮肤,上面的工厂类显然满足不了,需要增加一个 if 判断分支才能支持。而且当产品类型较多时,简单工厂的 if 判断将会非常多,不容易维护。
工厂方法模式

工厂方法模式的定义为:定义一个用于创建对象的接口或抽象类,让子类决定实例化哪一个类。
我们来画一下工厂方法模式下,女娲造人的类图:



其中,Human接口及其子类的代码不变,增加了一个抽象工厂AbstractHumanFactory,里面定义了一个造人的方法 createHuman(),具体创造什么类型的人由其子工厂实现。
抽象工厂类及其子工厂类如下:



女娲造人的方式如下:



执行之后发现结果不变。
工厂方法模式的优缺点

工厂方法模式的优点:遵循了开闭原则,扩展性极强。比如现在要增加一个绿皮肤的人类,我们只需要增加一个创建绿皮肤人类的工厂,这个工厂继承自抽象工厂即可,不需要改变原有代码,可维护性高。
工厂方法模式的缺点:增加了类的数量,当有成千上万个类型的产品时,就需要有成千上万个工厂类来生产这些产品。
抽象工厂模式

在工厂方法模式中,一个具体的工厂负责生产一类具体的产品,即一对一的关系,但是,如果需要一个具体的工厂生产多种产品对象,比如,生产不同肤色的男人和女人,那么就需要用到抽象工厂模式了。我们重新设计下这个功能的类图:



抽象工厂我们定义了两个方法,createMan() 和 createWoman()用来表示生产男人和女人,不管男人或女人,都有不同的肤色,所以我们定义了三个子工厂用来创建不同肤色的人(包括男人和女人),这三个子工厂重写了父类工厂的两个方法。具体实现代码如下。
Human接口及其两个实现类:



三种肤色的男人和女人:



抽象工厂代码:



具体工厂代码:



女娲使用工厂创造人类:



OK,女娲使用抽象工厂模式造人完成。
抽象工厂模式的优缺点

抽象工厂模式的优点:增加固定类型产品的不同具体工厂比较方便。例如现在女娲要创造一个绿皮肤的人,只需要再创建一个绿皮肤人的工厂继承抽象工厂就可以了。
抽象工厂模式的缺点:类图优点复杂,可读性没有工厂方法模式那么好。
点个关注吧,我会持续更新~~
您也可以关注我的微信公众号:Java架构成长之路,每天为您推送各种干货!
回复

举报

1

主题

4

帖子

4

积分

新手上路

Rank: 1

积分
4
发表于 2022-9-20 18:02:36 | 显示全部楼层
挺好的,收藏
回复

举报

1

主题

7

帖子

10

积分

新手上路

Rank: 1

积分
10
发表于 2022-9-20 18:02:45 | 显示全部楼层
我喜欢这个传说,里面蕴含着某种平等思想
回复

举报

2

主题

6

帖子

13

积分

新手上路

Rank: 1

积分
13
发表于 2022-9-20 18:03:38 | 显示全部楼层
女娲造人,工厂造[酷]
回复

举报

4

主题

9

帖子

17

积分

新手上路

Rank: 1

积分
17
发表于 2022-9-20 18:04:18 | 显示全部楼层
clazz instanceof WhiteHuman.class为什么我的这句话会报错
回复

举报

2

主题

5

帖子

11

积分

新手上路

Rank: 1

积分
11
发表于 2022-9-20 18:05:02 | 显示全部楼层
instanceof后面不能跟泛型!!!
Class<BlackHuman> blackHumanClass = BlackHuman.class
这里的反射后的类相当于一个泛型,会报错啊
回复

举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|多点娱乐

GMT+8, 2025-4-12 03:29 , Processed in 0.127158 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表