我所理解的抽象工厂模式是对普通工厂模式的一种层次化的组织。它将构成对象类别划分成多个维度,各个维度分别创建自己的普通工厂,并用一个统一的入口来封装对各个普通工厂的引用。抽象工厂模式对于有多个维度的对象的构造有着很好的结构化和便于扩展的作用。
相关介绍
在经典书籍GoF中,抽象工厂模式的介绍如下
意图:提供一个接口以创建一系列相关或相互依赖的对象,而无需执行它们具体的类。
动机:考虑一个支持多种视感标准(可以理解为主题)的用户界面工具包,为保证视感风格标准之间的可移植性,一个应用不应该为一个特定的视感外观硬编码它的组件。
书里的内容可能比较难理解,不过在 设计模式学习网站 中,有一个抽象工厂模式的例子–家具。一件家具有两个维度的属性:功能和样式。按功能分可以分为椅子、沙发、桌子;按样式分可以分为Art Deco, Victorian, Modern。一共可能出现的家具组合是3*3种。
我们可以为每一种都创建一个构造函数,并使用一个大的工厂方法包装对外的实例化接口。但是这样会使得工厂内部代码非常多,且后续每个维度的扩展都需要增加另一个维度的属性类别数个构造函数,维护成本较高。

究其原因,普通的工厂模式并没有处理维度之间的关系,它只是简单平铺了所有维度的可能组合。而抽象工厂在多个维度之间建立了层次关系,用一个抽象工厂来封装几个具体工厂。类图如下:

下面是一段伪代码,以mac, windows主题为例。
// Abstract Factory 抽象工厂的接口,里面封装了多个工厂方法
interface GUIFactory is
method createButton():Button
method createCheckbox():Checkbox
// Concrete Factory1 具体工厂-mac,需要实现抽象工厂要求的每个方法,内部自行保证各个方法返回的组件是同一个风格的
class MacFactory implements GUIFactory is
method createButton():Button is
return new MacButton()
method createCheckbox():Checkbox is
return new MacCheckbox()
// Concrete Factory2 具体工厂-windows
class WinFactory implements GUIFactory is
method createButton():Button is
return new WinButton()
method createCheckbox():Checkbox is
return new WinCheckbox()
实际案例
以下的案例脱胎于实际的工作,隐去了和业务相关的内容。它是一段用来区分两种主题的代码。抽象工厂的定义中包含两个元素:使用的组件和是否该展示该组件。
/**
* ConcreteFactory1
* 指示器组件工厂
* @param type
*/
export const indicatorComponentFactory = (type: EIndicatorType) => {
switch (type) {
case EIndicatorType.Normal:
return NormalIndicator; // 此处引用的是具体的组件定义,略去,下同
case EIndicatorType.Elderly:
return ElderlyIndicator;
default:
return NormalIndicator;
}
};
/**
* ConcreteFactory2
* 是否需要展示的工厂
*/
export const showIndicatorFactory = (type: EIndicatorType) => {
switch (type) {
case EIndicatorType.Normal:
return (dates: unknown[]) => someLogic(dates); // 具体逻辑隐去
case EIndicatorType.Elderly:
return (dates: unknown[]) => someOtherLogic(dates);
default:
return (dates: unknown[]) => someLogic(dates);
}
}
/**
* AbstractFactory
* 返回一整套风格一致的配置
* @param type
*/
export const indicatorFactory = (type: EIndicatorType): IIndicatorFactory => {
return {
Component: indicatorComponentFactory(type),
show: showIndicatorFactory(type),
};
};
本人对抽象工厂模式的理解可能也不是很透彻,如果对此篇文章有何想法欢迎探讨。
3744

被折叠的 条评论
为什么被折叠?



