抽象工厂模式(Abstract Factory)

在上一篇中,我们用工厂方法模式 解决了"如何创建某一种对象"的问题。

但在真实项目中,你很快会遇到更复杂的情况:

不是创建一个对象,而是创建"一整套相关对象"。

这正是抽象工厂模式存在的原因。


一、什么时候工厂方法不够用

先看一个典型业务场景:

  • 系统需要支持 多种支付渠道

  • 每种支付渠道,都包含:

    • 支付接口
    • 对账接口
    • 退款接口

也就是说:

对象之间存在"成组出现"的关系。

如果仍然使用工厂方法:

python 复制代码
pay = PaymentFactory.create("wechat")
refund = RefundFactory.create("wechat")
recon = ReconciliationFactory.create("wechat")

问题来了:

  • 调用方需要记住多组工厂
  • 容易出现"混用产品族"的问题
  • 结构开始变得混乱

二、抽象工厂模式是什么

**抽象工厂模式(Abstract Factory)**的定义:

提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类。

核心关键词只有一个:

产品族(Product Family)


三、抽象工厂模式的结构

抽象工厂模式包含四个核心角色:

  1. 抽象产品 A
  2. 抽象产品 B
  3. 抽象工厂
  4. 具体工厂(对应一个产品族)

四、用支付系统举一个完整示例

1. 抽象产品

python 复制代码
from abc import ABC, abstractmethod

class Payment(ABC):
    @abstractmethod
    def pay(self, amount):
        pass


class Refund(ABC):
    @abstractmethod
    def refund(self, amount):
        pass

2. 具体产品(微信产品族)

python 复制代码
class WeChatPay(Payment):
    def pay(self, amount):
        print(f"微信支付 {amount}")


class WeChatRefund(Refund):
    def refund(self, amount):
        print(f"微信退款 {amount}")

3. 具体产品(支付宝产品族)

python 复制代码
class AliPay(Payment):
    def pay(self, amount):
        print(f"支付宝支付 {amount}")


class AliRefund(Refund):
    def refund(self, amount):
        print(f"支付宝退款 {amount}")

4. 抽象工厂

python 复制代码
class PayFactory(ABC):
    @abstractmethod
    def create_payment(self) -> Payment:
        pass

    @abstractmethod
    def create_refund(self) -> Refund:
        pass

5. 具体工厂

python 复制代码
class WeChatFactory(PayFactory):
    def create_payment(self) -> Payment:
        return WeChatPay()

    def create_refund(self) -> Refund:
        return WeChatRefund()


class AliPayFactory(PayFactory):
    def create_payment(self) -> Payment:
        return AliPay()

    def create_refund(self) -> Refund:
        return AliRefund()

6. 使用方式

python 复制代码
factory = WeChatFactory()

payment = factory.create_payment()
refund = factory.create_refund()

payment.pay(100)
refund.refund(50)

调用方只关心:

  • 使用哪一个"产品族"
  • 不关心具体类名

五、抽象工厂带来的好处

1. 保证产品族一致性

  • 不会混用微信支付 + 支付宝退款
  • 从结构上杜绝错误

2. 高度解耦

  • 使用方只依赖抽象
  • 完全不知道具体实现类

3. 易于切换产品族

python 复制代码
factory = AliPayFactory()

一行代码切换整个系统的实现。


六、抽象工厂的代价

抽象工厂并不是"免费午餐"。

缺点:

  • 类数量明显增加
  • 结构复杂度上升
  • 新增产品类型成本高

注意区别:

  • 新增产品族(如新增"银联"):容易
  • 新增产品类型(如新增"对账接口"):需要修改所有工厂

七、工厂方法 vs 抽象工厂

对比点 工厂方法 抽象工厂
创建对象 单一对象 一组对象
产品关系 无强关联 同一产品族
复杂度 中 高
使用场景 对象类型多 产品族切换

八、Python 项目中的实际建议

在 Python 项目中:

  • 小系统:工厂方法足够
  • 中大型系统:产品族明确 → 抽象工厂
  • 不要一上来就抽象工厂
  • 让需求驱动设计,而不是反过来

九、总结

抽象工厂模式解决的是:

"如何成组地创建相互关联的对象"

它常用于:

  • 跨平台实现
  • 多渠道系统
  • 插件化架构
  • 大型框架底层设计
相关推荐
CoderYanger几秒前
Java EE 进阶:5. Spring IoC&DI(第三弹):Spring DI
java·开发语言·spring boot·spring·面试·java-ee·mvc
梯度下降者1 分钟前
Python从0到100(三):Python中的变量介绍
python·作用域·变量·数据类型·计算机常识
AIFQuant6 分钟前
Python期货行情API接入:股指、黄金、原油多品种数据管道实战
开发语言·python·金融·区块链·量化开发
一条泥憨鱼16 分钟前
【Kafka】零基础学习教程
java·分布式·学习·kafka
威哥爱编程25 分钟前
Python 智能体开发实战 07:让它查课表它张口就编?给 Agent 接上真正能动手的工具
python·agent
Wang's Blog26 分钟前
Java 项目实战:交友项目 - 即时通信总结:全链路复盘、可复用清单与自检
java·python·交友
文丑颜不良啊26 分钟前
LeetCode1501~1520题目解析
java·leetcode
2601_9628857231 分钟前
按主板/科创/创业/北交分板扫描选股
python
威哥爱编程32 分钟前
Python 智能体开发实战 08:上线第一天就挂?给 Agent 装上重试、超时和降级三条保险丝
python·agent
Dmz丶36 分钟前
前端转 AI 100 天 Day 35:结构化输出——让 LLM 稳定返回 JSON
python