设计模式(4)-抽象工厂模式

抽象工厂模式是什么?

前面两节分别介绍了简单工厂模式和工厂模式。其中,简单工厂模式提供了单个创建接口,通过指定入参来创建不同的具体产品,比如水果农场例子中的苹果和葡萄。工厂模式则利用多态性,采用抽象工厂和具体的苹果工厂、葡萄工厂来实现创建水果对象的功能,生产新的水果只需添加新的具体工厂即可,符合“开闭原则”。

工厂模式中,一个抽象工厂可以处理一种抽象产品,那么,如果是两种抽象产品呢?如果这两种产品没有关联,自然可以使用两个抽象工厂来处理,仍旧使用工厂模式。

https://s3.bmp.ovh/imgs/2021/10/7b3f2b4e9f7922d6.jpeg

一种特殊的情况是:这两种产品的层次结构是类似的,一个典型的例子是常见的图形界面,无论在windows、linux、还是macos,都有窗口、按钮、文本框、复选框等,不同之处只是UI风格不同而已。通过提取多个抽象产品的层次结构,抽象出一个相应的工厂层次结构。

抽象工厂模式类图如下:

https://s3.bmp.ovh/imgs/2021/10/d93687e89677ff1b.jpeg

从图中右侧可以看出,这个模式下的产品存在两种划分:
(1)横向上,同一抽象产品下 AbstracetProductA 的两种具体产品ConcreteProductA1 和 ConcreteProductA2,对应于左侧两种不同的具体工厂类 ConcreteFactory1 和 ConcreteFactory2,比如:windows的Push按钮和Toggle按钮。
(2)纵向上,在不同产品体系中的两种类似的产品,ConcreteProductA1 和 ConcreteProductB1,对应于左侧同一具体工厂类的两种方法:CreateProductA()CreateProductB()。比如:windows的Push按钮和macos的Push按钮。

如何确定哪些具体产品归纳到横向划分呢,其实简单归纳就是同一产品族,windows上的不同按钮都是为windows视窗系统这个大产品的其中一个组件。反过来,windows的Push按钮和macos的Push按钮不能组成一个具体产品,风格完全不搭。

最后,思考一下,为什么这个模式取名为抽象工厂模式,个人理解是它将工厂从只生产某一类产品的角色中抽象出来,得到能生产多种相同产品体系的一个抽象的工厂。一个生活中的例子:服装厂夏天可以生产男式T恤和女士T恤,冬天生产男式羽绒服和女士羽绒服,从中就可以抽出一个生产男式衣服和女式衣服的“抽象”服装厂,按季节生产不同的具体服装。

代码示例

暂略

参考

《Java与模式》第14章