二十三种设计模式解读——什么是抽象工厂模式
author:陈镇坤27
日期:2022年2月10日
一、抽象工厂方法模式
1、定义
Provide an interface for creating families of related or dependent objects without specifying
their concrete classes.
翻译:提供一个接口来创建相似的、有关联的、互相依赖的实体,而不是指定其具体的实现类。
怎么理解?
简单回顾下工厂方法模式:一个抽象的产品类,有一个或多个产品实现类。通过利用工厂类,可以一对一或一对多地生成指定的产品实现类。
在之前的工厂方法模式示例中,我们的工厂类输出参数为对应具体的实现类。并且基本上只有一个抽象的父类。
而抽象工厂方法模式最大的特点是,有多个抽象类,工厂类的出参为抽象类。
可以这么理解:抽象工厂方法模式,是在产品抽象类与产品具体实现类之间,新增了一层抽象类的介质,该抽象类表达“产品族”的概念,是两个或多个的产品族在许多功能、属性上的共性约束,然后再通过该介质的子类来表达“产品等级”的差异。
PS:这里说的产品等级,是我们要表现出来的差异。
例如两个有关联、拥有许多共性的服务,就是两个产品族。每个服务都可以在电脑端和手机端存在,在不同端的表现即为“产品等级”。
如果到这里还不好理解,就结合下面的示例讲解再看看。
2、应用场景
屏蔽调用者对具体实现类的了解,表达对象族的差异——产品等级。
3、通用范本
注意,这里的圈1、2表示产品等级。
有两类产品,叫A和B,两者有许多的共性(都有形状、讲话等属性),所以在它们之上可以抽象出一个更大的抽象类——AbstractProduct(这里省去了)。每个产品类,都存在两个不同情境下的产品等级,一个是产品等级1,一个是产品等级2。等级1用于电脑端,等级2用于手机端。
对应的,抽象工厂类会约定生成产品族的方法。这里是约定createProductA和createProductB。由于每个产品组都有不等的区分产品等级的子类,为此,每个产品等级对应一个工厂实现类。
4、示例讲解
有生产机器人的需求,要生产两款机器人。
它们都能说话、跳舞、展示等级。
机器人a、b是两个不同的款式。
但不论如何,它们的基本功能相似,只是现在两条生产线要并行,要清晰地区分开来两者,方便封装等等。
同时,机器人等级决定价格。所以,规定等级1的生产线是一个作业区,等级2的生产线是一个作业区,每个作业区可以同时生产a、b。
最后类图如下:
客户端创建了两个工厂实例,分别是ProductLevel1Factory,ProductLevel2Factory,每个工厂都可以生产a、b。
工厂的方法出参用Product接收。
最后,负责生产的人,通过工厂实例,在控制室(client)中便可以直接操控机器人生产,而完全不用和机器人实体接触(client屏蔽具体的实现类)。
下方是调用端的代码,可以看出调用者完全不需要了解产品的具体实现。
public static void main(String[] args) {
AbstractProductFactory factory = new ProductLevel1Factory();
Product productA = factory.createProductA();
}
5、拓展
暂时没有其他拓展模式可讲述。
PS:原作当中对这该原则的描述,太费解了,而且讲到产品族优点时,提到的约束例子也无法在书中案例中实现,具体就不解释了。只简单提下他想实现的方案(这里用我自己的例子作转换):
控制生产等级1的产品和等级2产品的比例。比如每生成2个等级1产品,才能生成1个等级2产品。
问题:产品族的拓展,需要在抽象工厂类上直接新增创建新产品族的抽象方法,这违背了开闭原则。
原因是所有的抽象工厂子类都必须实现该新增的抽象方法。
6、总结
抽象工厂模式的优点:高层模块调用不需要了解具体的子类;在工厂中实现了两个相关联产品族的创建;
抽象工厂模式的缺点:产品族拓展困难;
最后,建议在需要创建有多个具备相似特性的业务产品场景上,可以使用抽象工厂模式。