📋 Research Summary

抽象工厂模式处理的是"产品族"的创建问题。在实际应用中,UI 框架(如 Qt、Flutter)使用此模式确保跨平台组件风格一致。与工厂方法关注"单个产品"不同,抽象工厂关注"一组相关产品"的协调创建。


🌱 逻辑原点

如果你的客厅买了现代风格的沙发,但餐厅却摆了维多利亚风格的椅子,这种混搭的混乱如何避免?

单个产品创建与产品族一致性的矛盾:每个组件单独创建时都是合法的,但组合在一起却风格冲突。

🧠 苏格拉底式对话

1️⃣ 现状:最原始的解法是什么?

为每个产品单独使用工厂方法:

class ModernUIFactory:
    def create_button(self): return ModernButton()
    def create_sofa(self): return ModernSofa()

class VictorianUIFactory:
    def create_button(self): return VictorianButton()
    def create_sofa(self): return VictorianSofa()

# 客户端
button = factory.create_button()
sofa = factory.create_sofa()  # 如果这里不小心用错工厂...

优点:每个产品都有独立的创建逻辑。
问题:客户端仍然需要分别调用多个工厂方法,可能混用不同风格的工厂。

2️⃣ 瓶颈:规模扩大 100 倍时会在哪里崩溃?

当产品族扩展到 10 个产品(按钮、沙发、桌子、灯具、地毯…),且有 5 种风格(现代、维多利亚、装饰艺术、极简、工业)时:

  • 组合爆炸:客户端代码需要知道 50 个具体类的存在
  • 风格不一致风险:A 模块用现代工厂创建按钮,B 模块用维多利亚工厂创建沙发
  • 约束难以强制:语言层面无法阻止混用不同风格的产品

核心矛盾:我们需要"风格一致性"这个跨产品的约束,但单个工厂方法无法表达这种关联。

3️⃣ 突破:必须引入什么新维度?

将产品族作为一等公民

不是"分别创建各个产品",而是"创建一个完整的产品族"。工厂不再是一个方法,而是一个接口,定义了创建整个产品族的所有方法:

抽象工厂:我承诺能创建按钮、沙发、桌子
现代工厂:我的按钮是 ModernButton,沙发是 ModernSofa...
维多利亚工厂:我的按钮是 VictorianButton,沙发是 VictorianSofa...

这就是抽象工厂的本质:将"产品族一致性"作为创建契约的一部分

📊 视觉骨架

creates

creates

creates

creates

«interface»

AbstractFactory

+createButton() : Button

+createSofa() : Sofa

+createTable() : Table

ModernFactory

+createButton() : ModernButton

+createSofa() : ModernSofa

+createTable() : ModernTable

VictorianFactory

+createButton() : VictorianButton

+createSofa() : VictorianSofa

+createTable() : VictorianTable

«interface»

Button

«interface»

Sofa

ModernButton

ModernSofa

VictorianButton

VictorianSofa

关键洞察:抽象工厂的价值不在于"创建",而在于"约束"。它用类型系统强制保证了:从一个工厂创建的所有产品必然是同一风格。

⚖️ 权衡模型

公式:

Abstract Factory = 解决了产品族一致性 + 牺牲了新产品的扩展性 + 增加了接口的复杂度

代价分析:

  • 解决: 产品族风格一致性、客户端与具体类完全解耦、切换风格只需换一个工厂
  • 牺牲: 新增产品类型困难(需要修改所有工厂实现)、接口稳定性要求高
  • ⚠️ 增加: 接口复杂度(工厂接口随产品类型增长)、理解成本(需要理解产品族概念)

使用建议:当系统需要支持多套"风格"或"主题",且每套风格包含多个相互关联的组件时使用。不要为单个产品使用抽象工厂。

🔁 记忆锚点

from abc import ABC, abstractmethod

class UIFactory(ABC):
    """
    抽象工厂的本质:产品族的创建契约
    """
    
    @abstractmethod
    def create_button(self) -> "Button":
        """同一工厂创建的按钮和沙发风格必然一致"""
        pass
    
    @abstractmethod
    def create_sofa(self) -> "Sofa":
        pass

def client_code(factory: UIFactory) -> None:
    """
    客户端完全不知道具体风格,但风格一致性由类型系统保证
    """
    button = factory.create_button()  # 现代 or 维多利亚?不知道,也不关心
    sofa = factory.create_sofa()       # 必然与 button 同风格
    button.render()
    sofa.lay_on()

一句话本质: 抽象工厂模式 = 将"产品族一致性"编码到类型系统中


Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐