漫画:什么是 “抽象工厂模式” ?

百家 作者:CSDN 2020-09-16 21:44:59

作者 |?小灰
来源 | 程序员小灰(ID:chengxuyuanxiaohui)
所谓“工厂模式”,是三种常见设计模式的统称,它们分别是简单工厂模式、工厂方法模式、抽象工厂模式。
上一期的漫画中,我们介绍了简单工厂模式和工厂方法模式的特点和应用场景,没看过的小伙伴可以看这篇文章:漫画:设计模式之 “工厂模式”
这一期,我们来介绍抽象工厂模式,以及Spring框架当中对工厂模式的应用。
比如,业务中需要创建口罩、防毒面具、防护服这三种产品,而每一种产品有包含高端和低端两类,按照工厂方法模式的解决方案,需要创建的类如下:
如图所示,每一个产品类都对应着一个工厂类,当产品数量很多的时候,工厂类的数量也会越老越多,搞得系统非常复杂。
这时候我们该怎么办呢?
首先看一下产品类的代码,口罩和防护服是两个抽象接口,分别拥有高端和低端两个实现类:

public?interface?IMask?{
????void?showMask();
}

public?class?LowEndMask?implements?IMask?{
????@Override
????public?void?showMask(){
????????System.out.println("我的低端口罩");
????}
}

public?class?HighEndMask?implements?IMask?{
????@Override
????public?void?showMask()?{
????????System.out.println("我是高端口罩");
????}
}

public?interface?IProtectiveSuit?{
????void?showSuit();
}

public?class?LowEndProtectiveSuit?implements?IProtectiveSuit?{
????@Override
????public?void?showSuit()?{
????????System.out.println("我是低端防护服");
????}
}

public?class?HighEndProtectiveSuit?implements?IProtectiveSuit?{
????@Override
????public?void?showSuit()?{
????????System.out.println("我是高端防护服");
????}
}

接下来是工厂类,由于产品分成了高端和低端两大组,工厂也相应分成了高端工厂和低端工厂,各自负责组内产品的创建:

public?interface?IFactory?{
????//创建口罩
????IMask?createMask();
????//创建防护服
????IProtectiveSuit?createSuit();
}

public?class?LowEndFactory?implements?IFactory?{
????@Override
????public?IMask?createMask()?{
????????IMask?mask?=??new?LowEndMask();
????????//?.....
????????//??LowEndMask的100行初始化代码
????????return?mask;
????}

????@Override
????public?IProtectiveSuit?createSuit()?{
????????IProtectiveSuit?suit?=??new?LowEndProtectiveSuit();
????????//?.....
????????//??LowEndProtectiveSuit的100行初始化代码
????????return?suit;
????}
}

public?class?HighEndFactory?implements?IFactory?{
????@Override
????public?IMask?createMask()?{
????????IMask?mask?=??new?HighEndMask();
????????//?.....
????????//?HighEndMask的100行初始化代码
????????return?mask;
????}

????@Override
????public?IProtectiveSuit?createSuit()?{
????????IProtectiveSuit?suit?=??new?HighEndProtectiveSuit();
????????//?.....
????????//??HighEndProtectiveSuit的100行初始化代码
????????return?suit;
????}
}

最后是客户端代码,通过实例化不同的工厂子类,调用不同的创建方法,可以创建出不同的产品:

public?class?Test?{

????public?static?void?main(String[]?args)?{
????????IFactory?factoryA?=?new?LowEndFactory();
????????IFactory?factoryB?=?new?HighEndFactory();
????????//创建低端口罩
????????IMask?maskA?=?factoryA.createMask();
????????//创建高端口罩
????????IMask?maskB?=?factoryB.createMask();
????????//创建低端防护服
????????IProtectiveSuit?suitA?=?factoryA.createSuit();
????????//创建高端防护服
????????IProtectiveSuit?suitB?=?factoryB.createSuit();

????????maskA.showMask();
????????maskB.showMask();
????????suitA.showSuit();
????????suitB.showSuit();
????}
}

简单工厂模式:
简单工厂模式有唯一的工厂类,工厂类的创建方法根据传入的参数做if-else条件判断,决定最终创建什么样的产品对象。
工厂方法模式:
工厂方法模式由多个工厂类实现工厂接口,利用多态来创建不同的产品对象,从而避免了冗长的if-else条件判断。
抽象工厂模式:
抽象工厂模式把产品子类进行分组,同组中的不同产品由同一个工厂子类的不同方法负责创建,从而减少了工厂子类的数量。

熟悉spring框架的小伙伴,一定知道spring的一个重要特性:依赖注入(DI)。
通过spring的依赖注入,开发人员不需要在业务代码中手动实例化bean对象,也不需要知道任何工厂类。
bean对象从创建到销毁的整个过程,完全交给spring容器来管理,用户需要做的仅仅是在xml配置文件中(或使用注解)设置bean的各项属性:

<bean?id="userController"?class="com.xiaohui.controller.UserController">
????<constructor-arg?name="userService"?ref="userService"></constructor-arg>
</bean>


<bean?id="userService"?class="com.xiaohui.service.UserService">

根据上面的配置,spring容器会动态创建UserController对象,并创建UserController所依赖的UserService对象。
如果开发人员希望把userService这个bean对象的实现类换成另一个类,并不需要改动任何代码,只需要修改配置文件中对应bean的class属性即可。
在大多数情况下,我们使用new关键字创建对象,对象所属的class是在代码中明确定义好的。
但是在少数情况下,我们需要借助class的元信息(比如完整类名),在程序运行期间动态创建对象,这就用到了Java的反射。
当我们在spring配置文件中配置了相应的bean,启动项目,spring会为我们解析xml配置文件,并根据bean的不同生命周期,由spring内部的“工厂”创建出bean对象。
对spring依赖注入原理有兴趣的小伙伴,可以阅读spring源码中的BeanFactory接口,以及相关的实现类。


更多精彩推荐

?没有 5G 版 iPhone 的苹果秋季发布会,发布了些什么?

?对话阿里云李飞飞:云原生数据库的时代来了

?IT 往事录:苹果 Mac 之父,却在 Mac 问世前黯然退场

?B 站神曲damedane:精髓在于换脸,五分钟就能学会

?可怕!公司部署了一个东西,悄悄盯着你……

?极简椭圆曲线密码学入门
点分享
点点赞
点在看

关注公众号:拾黑(shiheibook)了解更多

[广告]赞助链接:

四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

图库
公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接