抽象工厂

抽象工厂
抽象工厂是一种创建型设计模式,它能创建一系列相关的对象,而无需指定其具体类。抽象工厂模式通常基于一组工厂方法,但你也可以使用原型模式来生成这些类的方法。
问题分析
譬如某家具店有一系列相关产品,例如椅子(Chair
抽象工厂模式建议为系列中的每件产品明确声明接口(例如椅子、沙发或咖啡桌

对于系列产品的每个变体,我们都将基于抽象工厂接口创建不同的工厂类。每个工厂类都只能返回特定类别的产品,例如,现代家具工厂(ModernFurnitureFactory)只能创建现代椅子(MordernChair
优劣对比
如果代码需要与多个不同系列的相关产品交互,但是由于无法提前获取相关信息,或者出于对未来扩展性的考虑,你不希望代码基于产品的具体类进行构建,在这种情况下,你可以使用抽象工厂。
抽象工厂为你提供了一个接口,可用于创建每个系列产品的对象。只要代码通过该接口创建对象,那么你就不会生成与应用程序已生成的产品类型不一致的产品。如果你有一个基于一组抽象方法的类,且其主要功能因此变得不明确,那么在这种情况下,你可以考虑使用抽象工厂。在设计良好的程序中,如果一个类与多种类型产品交互,就可以考虑将工厂方法抽取到独立的工厂类或具备完整功能的抽象工厂类中。
实现方式
抽象产品(Abstract Product)为构成系列产品的一组不同但相关的产品声明接口。具体产品(Concrete Product)是抽象产品的多种不同类型实现。所有变体(维多利亚

-
首先以不同的产品类型与产品变体为维度绘制矩阵,为所有产品声明抽象产品接口,然后让所有具体产品类实现这些接口。
-
然后声明抽象工厂接口,并且在接口中为所有抽象产品提供一组构造方法。
-
接下来为每种产品变体实现一个具体工厂类,在应用程序中开发初始化代码。该代码根据应用程序配置或当前环境,对特定具体工厂类进行初始化。
-
最后将该工厂对象传递给所有需要创建产品的类。找出代码中所有对产品构造方法的直接调用,将其替换为对工厂对象中相应构造方法的调用。
尽管具体工厂会对具体产品进行初始化,其构造函数签名必须返回相应的 抽象 产品。这样,使用工厂类的客户端代码就不会与工厂创建的特定产品变体耦合。客户端(Client)只需通过抽象接口调用工厂和产品对象,就能与任何具体工厂
案例:跨平台组件
通过应用抽象工厂模式,使得客户端代码无需与具体

跨平台应用中的相同
// 抽象工厂接口声明了一组能返回不同抽象产品的方法。这些产品属于同一个系列
// 且在高层主题或概念上具有相关性。同系列的产品通常能相互搭配使用。系列产
// 品可有多个变体,但不同变体的产品不能搭配使用。
interface GUIFactory is
method createButton():Button
method createCheckbox():Checkbox
// 具体工厂可生成属于同一变体的系列产品。工厂会确保其创建的产品能相互搭配
// 使用。具体工厂方法签名会返回一个抽象产品,但在方法内部则会对具体产品进
// 行实例化。
class WinFactory implements GUIFactory is
method createButton():Button is
return new WinButton()
method createCheckbox():Checkbox is
return new WinCheckbox()
// 每个具体工厂中都会包含一个相应的产品变体。
class MacFactory implements GUIFactory is
method createButton():Button is
return new MacButton()
method createCheckbox():Checkbox is
return new MacCheckbox()
// 系列产品中的特定产品必须有一个基础接口。所有产品变体都必须实现这个接口。
interface Button is
method paint()
// 具体产品由相应的具体工厂创建。
class WinButton implements Button is
method paint() is
// 根据 Windows 样式渲染按钮。
class MacButton implements Button is
method paint() is
// 根据 macOS 样式渲染按钮
// 这是另一个产品的基础接口。所有产品都可以互动,但是只有相同具体变体的产
// 品之间才能够正确地进行交互。
interface Checkbox is
method paint()
class WinCheckbox implements Checkbox is
method paint() is
// 根据 macOS 样式渲染复选框。
class MacCheckbox implements Checkbox is
method paint() is
// 根据 macOS 样式渲染复选框。
// 客户端代码仅通过抽象类型(GUIFactory、Button 和 Checkbox)使用工厂
// 和产品。这让你无需修改任何工厂或产品子类就能将其传递给客户端代码。
class Application is
private field button: Button
constructor Application(factory: GUIFactory) is
this.factory = factory
method createUI() is
this.button = factory.createButton()
method paint() is
button.paint()
// 程序会根据当前配置或环境设定选择工厂类型,并在运行时创建工厂(通常在初
// 始化阶段)。
class ApplicationConfigurator is
method main() is
config = readApplicationConfigFile()
if (config.OS == "Windows") then
factory = new WinFactory()
else if (config.OS == "Mac") then
factory = new MacFactory()
else
throw new Exception("错误!未知的操作系统。")
Application app = new Application(factory)
其运作方式如下:应用程序启动后检测当前操作系统。根据该信息,应用程序通过与该操作系统对应的类创建工厂对象。其余代码使用该工厂对象创建
这样一来,每次在应用程序中添加新的