Python设计模式 - 抽象工厂模式

定义

抽象工厂模式是一种创建型设计模式,它提供了一种创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

产品等级结构与产品族

为了更好地理解抽象工厂模式,先引入两个概念:

  1. 产品等级结构:就是产品的继承结构。例如电视机抽象类有A品牌电视机子类和B品牌电视机子类,那么抽象电视机和具体品牌的电视机就构成了一个产品等级结构。
  2. 产品族:同一个工厂生产的,位于不同产品等级结构中的一组产品。例如海尔工厂生产的海尔电视机、海尔电冰箱就构成了一个产品族。

结构

在这里插入图片描述

  • 抽象工厂(Abstract Factory):声明一组用于创建一个产品族产品的工厂方法,每个工厂方法对应一种产品。
  • 具体工厂(Concrete Factory):实现抽象工厂中的工厂方法,这些方法创建的产品构成了一个产品族,每种产品都位于不同的产品等级结构中。
  • 抽象产品(Abstract Product):定义产品对象的接口。
  • 具体产品(Concrete Product):实现产品接口的具体产品对象。

应用场景

  1. 跨平台的产品系列:当需要为不同的平台(如Windows、Mac、Linux)创建一系列相关的产品时,可以使用抽象工厂模式。每个具体工厂类实现工厂方法来创建一个平台的所有产品。例如,跨平台的GUI框架需要针对不同操作系统生成不同风格的按钮、文本框等组件。
  2. 使用多个产品族:系统中有多于一个的产品族,而每次只使用其中某一个产品族,客户端可以通过配置文件等方式来使得用户可以动态改变产品族,也可以很方便地增加新的产品族。例如,窗口中的按钮、文本框可以根据用户的选择按照不同的风格来展示。

优缺点

优点:

  1. 封装对象创建:抽象工厂模式将一系列相关对象的创建封装在一起,客户端无需关心对象的创建过程和具体类型。这减少了代码的耦合度,使系统更易于维护和扩展。
  2. 产品族的一致性:使用一个具体工厂创建的产品对象可以确保属于同一个产品族,且它们之间是兼容的。这避免了客户端在组合不同产品时可能出现的不兼容问题。
  3. 易于扩展:当需要引入新的产品族时,只需添加新的具体工厂类和对应的具体产品类,而不需要修改现有代码。这样能够确保系统的开放-封闭原则,即对扩展开放,对修改封闭。

缺点:

  1. 难以支持新产品类型:如果要添加新的产品等级结构,需要修改抽象工厂类及所有的具体工厂类,这违反了开放-封闭原则,增加维护成本。因此在使用抽象方法模式之前要进行全面考虑,尽量不要在设计完成后增加或删除产品等级结构。

代码示例

from abc import ABC, abstractmethod


# 抽象产品 - 按钮
class Button(ABC):
    @abstractmethod
    def click(self):
        pass


# 抽象产品 - 文本框
class TextBox(ABC):
    @abstractmethod
    def input(self, text):
        pass


# 具体产品 - Windows 按钮
class WindowsButton(Button):
    def click(self):
        print("Windows Button Clicked")


# 具体产品 - Windows 文本框
class WindowsTextBox(TextBox):
    def input(self, text):
        print(f"Windows TextBox input: {text}")


# 具体产品 - Mac 按钮
class MacButton(Button):
    def click(self):
        print("Mac Button Clicked")


# 具体产品 - Mac 文本框
class MacTextBox(TextBox):
    def input(self, text):
        print(f"Mac TextBox input: {text}")


# 抽象工厂
class GUIFactory(ABC):
    @abstractmethod
    def create_button(self):
        pass

    @abstractmethod
    def create_textbox(self):
        pass


# 具体工厂 - Windows 工厂
class WindowsFactory(GUIFactory):
    def create_button(self):
        return WindowsButton()

    def create_textbox(self):
        return WindowsTextBox()


# 具体工厂 - Mac 工厂
class MacFactory(GUIFactory):
    def create_button(self):
        return MacButton()

    def create_textbox(self):
        return MacTextBox()


# 客户端代码
def client(factory: GUIFactory):
    button = factory.create_button()
    textbox = factory.create_textbox()
    button.click()
    textbox.input("Hello World")


# 使用 Windows 工厂
print("Using Windows Factory:")
client(WindowsFactory())

# 使用 Mac 工厂
print("\nUsing Mac Factory:")
client(MacFactory())

抽象工厂模式和工厂方法模式的比较

抽象工厂模式是工厂方法模式的进一步延伸,我们从以下几点进行比较它们:

  1. 系统开销:工厂方法模式中的每个工厂只生产一种产品,可能会导致系统中存在大量的工厂类,会增加系统的开销。而抽象工厂模式将一些相关的产品组成一个“产品族”,由同一个工厂来统一生产,极大地减少了工厂类的数量。
  2. 扩展性:工厂方法模式增加新产品比较容易,只需要增加对应产品类和工厂方法类即可。抽象工厂模式增加新的产品族比较容易,但增加新的产品类型,需要修改抽象工厂类及所有的具体工厂类,扩展性稍差。
  3. 适用场景:工厂方法模式适用于系统只需要一个产品的多种变体的场景,抽象方法模式适用于系统需要创建多个相关产品族的场景。

参考

《设计模式的艺术》

  • 25
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值