目录
三、C++ 重构实战:用抽象工厂模式打造 “一键切换产品族” 的支付系统
需求:开发跨平台应用,支持 Windows 和 Mac 两套 UI 组件(按钮、输入框、下拉框),可一键切换平台。
需求:支持 MySQL 和 PostgreSQL 两种数据库,每种数据库包含连接、查询、事务 3 个配套操作,可动态切换数据库。
需求:游戏支持战士和法师两种职业,每种职业有配套的武器、防具、技能,切换职业时自动切换整套装备。

class 卑微码农:
def __init__(self):
self.技能 = ['能读懂十年前祖传代码', '擅长用Ctrl+C/V搭建世界', '信奉"能跑就别动"的玄学']
self.发量 = 100 # 初始发量
self.咖啡因耐受度 = '极限'
def 修Bug(self, bug):
try:
# 试图用玄学解决问题
if bug.严重程度 == '离谱':
print("这一定是环境问题!")
else:
print("让我看看是谁又没写注释...哦,是我自己。")
except Exception as e:
# 如果try块都救不了,那就...
print("重启一下试试?")
self.发量 -= 1 # 每解决一个bug,头发-1
# 实例化一个我
我 = 卑微码农()
引言:工厂方法不够用了?多产品族场景的创建噩梦

作为 C++ 开发者,你一定用工厂方法模式解决过对象创建问题 —— 比如支付系统中,微信支付由WechatPayFactory创建,支付宝由AlipayFactory创建,业务逻辑只需切换工厂即可切换支付方式。
但如果需求升级:支付系统不仅需要 “支付” 功能,还需要配套的 “退款”“对账” 功能 —— 微信支付对应WechatRefund“WechatReconciliation”,支付宝对应AlipayRefund“AlipayReconciliation”。此时用工厂方法模式,你会发现:
// 工厂方法模式的尴尬:每个产品对应一个工厂,工厂泛滥成灾
WechatPayFactory payFactory; // 微信支付工厂
WechatRefundFactory refundFactory; // 微信退款工厂
WechatReconciliationFactory reconFactory; // 微信对账工厂
// 业务调用:需要管理多个工厂,切换产品族(比如从微信换支付宝)要改3处
auto pay = payFactory.create();
auto refund = refundFactory.create();
auto recon = reconFactory.create();
这种场景下,工厂方法模式的弊端暴露无遗:
- 工厂泛滥:一个产品族(如微信支付相关)包含 N 个产品,就需要 N 个工厂,管理成本指数级增长;
- 切换繁琐:切换产品族(如从微信换成支付宝),需要修改所有工厂的创建逻辑,违反开放封闭原则;
- 业务耦合:业务代码需要同时依赖多个工厂,一旦工厂数量增加,调用逻辑变得臃肿混乱。
而抽象工厂模式(Abstract Factory Pattern),正是为解决 “多产品族创建” 而生的设计模式:通过定义 “抽象工厂”,让一个工厂负责创建同一产品族的多个相关产品(如微信工厂同时创建支付、退款、对账),业务逻辑只需依赖一个抽象工厂,切换产品族时只需换一个工厂实例,无需修改任何业务代码。
这篇文章不会堆砌复杂的 UML 图,而是用 C++ 实战场景 + 可运行代码 + 真实踩坑经验,带你彻底吃透抽象工厂模式。不管你是刚接触设计模式的新手,还是想解决多产品族创建混乱的开发者,读完这篇,你都能写出 “产品族一键切换,扩展不碰老代码” 的优雅架构。
一、先搞懂:抽象工厂模式到底是什么?

1.1 核心思想:“一个工厂,搞定一整套产品”
抽象工厂模式的核心是:定义一个抽象工厂接口,该接口负责创建一系列相关或相互依赖的产品(产品族),具体工厂实现这个接口,创建对应产品族的所有产品,业务逻辑通过依赖抽象工厂,实现产品族的一键切换。
用一句大白话解释:抽象工厂是 “工厂的工厂”,它不只是创建一个产品,而是创建一整套配套产品。比如:
- 手机品牌(抽象工厂):苹果工厂创建 iPhone(手机)+ AirPods(耳机)+ MagSafe(充电器)(同一产品族);华为工厂创建 Mate 系列(手机)+ FreeBuds(耳机)+ 华为充电器(同一产品族);
- 业务逻辑(用户)只需选择 “苹果工厂” 或 “华为工厂”,就能获得一整套配套产品,不用分别找手机工厂、耳机工厂。
1.2 关键概念:产品族 vs 产品等级结构(必懂!)
理解抽象工厂模式的关键,是区分 “产品族” 和 “产品等级结构”,这也是它和工厂方法模式的核心区别:
- 产品族:同一品牌 / 场景下的配套产品,比如 “微信支付 + 微信退款 + 微信对账”“Windows 按钮 + Windows 输入框 + Windows 下拉框”;
- 产品等级结构:不同品牌 / 场景下的同一类产品,比如 “微信支付 + 支付宝支付 + 银联支付”“Windows 按钮 + Mac 按钮 + Linux 按钮”。
用表格更直观:
| 维度 | 产品族(抽象工厂负责) | 产品等级结构(工厂方法负责) |
|---|---|---|
| 核心关系 | 配套使用(如支付 + 退款 + 对账) | 相互替代(如微信支付替代支付宝支付) |
| 创建主体 | 一个抽象工厂创建一整套产品 | 一个具体工厂创建一个产品 |
| 适用场景 | 需要切换整套配套产品 | 需要切换单个替代产品 |
举个生活化例子:
- 产品族:星巴克的 “咖啡 + 蛋糕 + 饮品”(配套购买);
- 产品等级结构:不同品牌的咖啡(星巴克咖啡、瑞幸咖啡,相互替代)。
抽象工厂模式的目标,就是让 “切换产品族” 像换一套星巴克套餐一样简单,而不是分别换咖啡、蛋糕、饮品。
1.3 抽象工厂的 4 个核心角色(和工厂方法对比)
抽象工厂模式的角色和工厂方法类似,但职责扩展到了 “产品族”:
- 抽象产品(Abstract Product):定义某一类产品的接口(如
IPay、IRefund),每个产品等级结构对应一个抽象产品; - 具体产品(Concrete Product):实现抽象产品的具体类(如
WechatPay、AlipayRefund),属于某个产品族; - 抽象工厂(Abstract Factory):定义创建同一产品族所有产品的接口(如
IPayFactory包含createPay()、createRefund()、createReconciliation()); - 具体工厂(Concrete Factory):实现抽象工厂接口,创建对应产品族的所有具体产品(如
WechatFactory创建微信支付、退款、对账)。
它们的关系:抽象工厂→创建→同一产品族的多个抽象产品,具体工厂→创建→同一产品族的多个具体产品。
1.4 和工厂方法模式的核心区别(避免混淆!)
很多开发者分不清抽象工厂和工厂方法,用一句话总结:
- 工厂方法模式:“一厂一品”,解决 “单个产品的替代问题”(如支付方式替代);
- 抽象工厂模式:“一厂多品(产品族)”,解决 “整套产品的切换问题”(如支付 + 退款 + 对账的整套切换)。
用表格对比更清晰:
| 特性 | 工厂方法模式 | 抽象工厂模式 |
|---|---|---|
| 工厂职责 | 创建单个产品 | 创建同一产品族的多个配套产品 |
| 产品关系 | 相互替代(产品等级结构) | 相互配套(产品族) |
| 扩展方式 | 新增产品→新增具体工厂 | 新增产品族→新增具体工厂;新增产品等级→修改抽象工厂(不推荐) |
| 适用场景 | 产品类型少,需灵活替代 | 产品族明确,需整体切换整套产品 |
| 复杂度 | 低(单个产品创建) | 中(多个产品创建,接口更复杂) |
简单说:如果你的场景是 “换单个零件”,用工厂方法;如果是 “换一整套装备”,用抽象工厂。
二、C++ 反例实战:工厂方法模式处理多产品族的混乱

为了让你直观感受抽象工厂的价值,我们先用工厂方法模式实现一个 “支付 + 退款 + 对账” 的多产品族场景,看看它有多混乱。
2.1 需求背景
实现一个电商支付系统,核心需求:
- 支持微信、支付宝两个产品族,每个产品族包含 3 个产品:支付(Pay)、退款(Refund)、对账(Reconciliation);
- 业务逻辑需要同时使用同一产品族的 3 个产品(比如创建订单后,支付成功→后续可能退款→每日对账);
- 未来可能新增 “银联” 产品族,不新增产品类型(仍为支付、退款、对账)。
2.2 工厂方法模式的混乱实现
#include <iostream>
#include <string>
#include <memory>
// ======================== 抽象产品(3个产品等级结构)========================
// 抽象产品1:支付
class IPay {
public:
virtual ~IPay() = default;
virtual void pay(double amount) = 0;
};
// 抽象产品2:退款
class IRefund {
public:
virtual ~IRefund() = default;
virtual void refund(double amount) = 0;
};
// 抽象产品3:对账
class IReconciliation {
public:
virtual ~IReconciliation() = default;
virtual void reconcile() = 0;
};
// ======================== 具体产品(微信产品族)========================
// 微信支付
class WechatPay : public IPay {
public:
void pay(double amount) override {
std::cout << "[微信] 发起支付:" << amount << "元" << std::endl;
}
};
// 微信退款
class WechatRefund : public IRefund {
public:
void refund(double amount) override {
std::cout << "[微信] 发起退款:" << amount << "元" << std::endl;
}
};
// 微信对账
class WechatReconciliation : public IReconciliation {
public:
void reconcile() override {
std::cout << "[微信] 每日对账,核对交易流水" << std::endl;
}
};
// ======================== 具体产品(支付宝产品族)========================
// 支付宝支付
class Alipay : public IPay {
public:
void pay(double amount) override {
std::cout << "[支付宝] 发起支付:" << amount << "元" << std::endl;
}
};
// 支付宝退款
class AlipayRefund : public IRefund {
public:
void refund(double amount) override {
std::cout << "[支付宝] 发起退款:" << amount << "元" << std::endl;
}
};
// 支付宝对账
class AlipayReconciliation : public IReconciliation {
public:
void reconcile() override {
std::cout << "[支付宝] 每日对账,核对交易流水" << std::endl;
}
};
// ======================== 工厂方法(6个工厂,每个产品对应一个)========================
// 微信支付工厂
class WechatPayFactory {
public:
std::unique_ptr<IPay> create() { return std::make_unique<WechatPay>(); }
};
// 微信退款工厂
class WechatRefundFactory {
public:
std::unique_ptr<IRefund> create() { return std::make_unique<WechatRefund>(); }
};
// 微信对账工厂
class WechatReconciliationFactory {
public:
std::unique_ptr<IReconciliation> create() { return std::make_unique<WechatReconciliation>(); }
};
// 支付宝支付工厂
class AlipayPayFactory {
public:
std::unique_ptr<IPay> create() { return std::make_unique<Alipay>(); }
};
// 支付宝退款工厂
class AlipayRefundFactory {
public:
std::unique_ptr<IRefund> create() { return std::make_unique<AlipayRefund>(); }
};
// 支付宝对账工厂
class AlipayReconciliationFactory {
public:
std::unique_ptr<IReconciliation> create() { return std::make_unique<AlipayReconciliation>(); }
};
// ======================== 业务模块(订单系统)========================
class OrderSystem {
public:
// 业务逻辑:支付→退款→对账(需要3个工厂)
void processOrder(bool useWechat, double amount) {
// 1. 创建对应产品族的3个工厂(混乱点1:工厂数量多,管理复杂)
std::unique_ptr<IPayFactory> payFactory;
std::unique_ptr<IRefundFactory> refundFactory;
std::unique_ptr<IReconciliationFactory> reconFactory;
if (useWechat) {
payFactory = std::make_unique<WechatPayFactory>();
refundFactory = std::make_unique<WechatRefundFactory>();
reconFactory = std::make_unique<WechatReconciliationFactory>();
} else {
payFactory = std::make_unique<AlipayPayFactory>();
refundFactory = std::make_unique<AlipayRefundFactory>();
reconFactory = std::make_unique<AlipayReconciliationFactory>();
}
// 2. 创建产品(混乱点2:需要调用3个工厂的create方法)
auto pay = payFactory->create();
auto refund = refundFactory->create();
auto recon = reconFactory->create();
// 3. 业务逻辑
pay->pay(amount);
refund->refund(amount * 0.5); // 假设退一半
recon->reconcile();
}
};
// 主函数测试
int main() {
OrderSystem orderSystem;
// 微信产品族
std::cout << "=== 测试微信产品族 ===" << std::endl;
orderSystem.processOrder(true, 199.9);
// 支付宝产品族
std::cout << "\n=== 测试支付宝产品族 ===" << std::endl;
orderSystem.processOrder(false, 299.9);
return 0;
}
2.3 反例代码的 4 大致命问题
这段代码能实现功能,但在实际开发中会让维护者崩溃:
- 工厂泛滥:2 个产品族 + 3 个产品 = 6 个工厂,新增 “银联” 产品族需要再加 3 个工厂,工厂数量爆炸式增长;
- 切换繁琐:业务模块切换产品族时,需要修改 3 个工厂的创建逻辑(
if-else里新增 3 行),违反开放封闭原则; - 业务耦合:业务模块需要管理多个工厂,还要手动匹配 “同一产品族的工厂”,一旦配错(比如微信支付 + 支付宝退款),会导致逻辑错误;
- 扩展成本高:如果新增产品类型(如 “对账明细导出”),需要新增 1 个抽象产品 + 2 个具体产品 + 2 个工厂,所有业务模块都要同步修改,牵一发而动全身。
这就是多产品族场景下工厂方法模式的瓶颈 —— 它只能处理 “单个产品的替代”,无法应对 “整套产品的切换”。而抽象工厂模式,正是为解决这个问题而生。
三、C++ 重构实战:用抽象工厂模式打造 “一键切换产品族” 的支付系统

针对反例的混乱,我们用抽象工厂模式重构,核心思路是 **“抽象工厂负责创建同一产品族的所有产品,业务模块只依赖一个抽象工厂”**:
- 定义抽象工厂
IPaymentFactory,包含创建支付、退款、对账 3 个产品的方法; - 每个具体工厂(
WechatFactory、AlipayFactory)实现抽象工厂,创建对应产品族的 3 个具体产品; - 业务模块
OrderSystem只依赖IPaymentFactory,切换产品族只需传入不同的具体工厂,无需修改业务代码。
3.1 重构后的完整代码
3.1.1 抽象产品(产品等级结构)
// IPay.h(抽象产品1:支付)
#ifndef I_PAY_H
#define I_PAY_H
#include <string>
class IPay {
public:
virtual ~IPay() = default;
virtual void pay(double amount) = 0;
virtual std::string getPayName() const = 0;
};
#endif // I_PAY_H
// IRefund.h(抽象产品2:退款)
#ifndef I_REFUND_H
#define I_REFUND_H
#include <string>
class IRefund {
public:
virtual ~IRefund() = default;
virtual void refund(double amount) = 0;
virtual std::string getRefundName() const = 0;
};
#endif // I_REFUND_H
// IReconciliation.h(抽象产品3:对账)
#ifndef I_RECONCILIATION_H
#define I_RECONCILIATION_H
#include <string>
class IReconciliation {
public:
virtual ~IReconciliation() = default;
virtual void reconcile() = 0;
virtual std::string getReconName() const = 0;
};
#endif // I_RECONCILIATION_H
3.1.2 具体产品(微信产品族)
// WechatPay.h(微信支付)
#ifndef WECHAT_PAY_H
#define WECHAT_PAY_H
#include "IPay.h"
class WechatPay : public IPay {
public:
void pay(double amount) override;
std::string getPayName() const override;
};
#endif // WECHAT_PAY_H
// WechatPay.cpp
#include "WechatPay.h"
#include <iostream>
void WechatPay::pay(double amount) {
std::cout << "[微信支付] 发起支付请求,金额:" << amount << "元" << std::endl;
// 实际调用微信支付SDK、签名校验等逻辑(简化)
}
std::string WechatPay::getPayName() const {
return "微信支付";
}
// WechatRefund.h(微信退款)
#ifndef WECHAT_REFUND_H
#define WECHAT_REFUND_H
#include "IRefund.h"
class WechatRefund : public IRefund {
public:
void refund(double amount) override;
std::string getRefundName() const override;
};
#endif // WECHAT_REFUND_H
// WechatRefund.cpp
#include "WechatRefund.h"
#include <iostream>
void WechatRefund::refund(double amount) {
std::cout << "[微信退款] 发起退款请求,金额:" << amount << "元" << std::endl;
// 实际调用微信退款SDK逻辑(简化)
}
std::string WechatRefund::getRefundName() const {
return "微信退款";
}
// WechatReconciliation.h(微信对账)
#ifndef WECHAT_RECONCILIATION_H
#define WECHAT_RECONCILIATION_H
#include "IReconciliation.h"
class WechatReconciliation : public IReconciliation {
public:
void reconcile() override;
std::string getReconName() const override;
};
#endif // WECHAT_RECONCILIATION_H
// WechatReconciliation.cpp
#include "WechatReconciliation.h"
#include <iostream>
void WechatReconciliation::reconcile() {
std::cout << "[微信对账] 对接微信商户平台,核对今日交易流水" << std::endl;
}
std::string WechatReconciliation::getReconName() const {
return "微信对账";
}
3.1.3 具体产品(支付宝产品族)
// Alipay.h(支付宝支付)
#ifndef ALIPAY_H
#define ALIPAY_H
#include "IPay.h"
class Alipay : public IPay {
public:
void pay(double amount) override;
std::string getPayName() const override;
};
#endif // ALIPAY_H
// Alipay.cpp
#include "Alipay.h"
#include <iostream>
void Alipay::pay(double amount) {
std::cout << "[支付宝支付] 发起支付请求,金额:" << amount << "元" << std::endl;
// 实际调用支付宝支付SDK逻辑(简化)
}
std::string Alipay::getPayName() const {
return "支付宝支付";
}
// AlipayRefund.h(支付宝退款)
#ifndef ALIPAY_REFUND_H
#define ALIPAY_REFUND_H
#include "IRefund.h"
class AlipayRefund : public IRefund {
public:
void refund(double amount) override;
std::string getRefundName() const override;
};
#endif // ALIPAY_REFUND_H
// AlipayRefund.cpp
#include "AlipayRefund.h"
#include <iostream>
void AlipayRefund::refund(double amount) {
std::cout << "[支付宝退款] 发起退款请求,金额:" << amount << "元" << std::endl;
// 实际调用支付宝退款SDK逻辑(简化)
}
std::string AlipayRefund::getRefundName() const {
return "支付宝退款";
}
// AlipayReconciliation.h(支付宝对账)
#ifndef ALIPAY_RECONCILIATION_H
#define ALIPAY_RECONCILIATION_H
#include "IReconciliation.h"
class AlipayReconciliation : public IReconciliation {
public:
void reconcile() override;
std::string getReconName() const override;
};
#endif // ALIPAY_RECONCILIATION_H
// AlipayReconciliation.cpp
#include "AlipayReconciliation.h"
#include <iostream>
void AlipayReconciliation::reconcile() {
std::cout << "[支付宝对账] 对接支付宝商户平台,核对今日交易流水" << std::endl;
}
std::string AlipayReconciliation::getReconName() const {
return "支付宝对账";
}
3.1.4 抽象工厂与具体工厂
// IPaymentFactory.h(抽象工厂:创建支付产品族的3个产品)
#ifndef I_PAYMENT_FACTORY_H
#define I_PAYMENT_FACTORY_H
#include "IPay.h"
#include "IRefund.h"
#include "IReconciliation.h"
#include <memory>
// 抽象工厂:负责创建同一产品族的3个产品(支付、退款、对账)
class IPaymentFactory {
public:
virtual ~IPaymentFactory() = default;
virtual std::unique_ptr<IPay> createPay() = 0;
virtual std::unique_ptr<IRefund> createRefund() = 0;
virtual std::unique_ptr<IReconciliation> createReconciliation() = 0;
};
#endif // I_PAYMENT_FACTORY_H
// WechatFactory.h(具体工厂:微信产品族)
#ifndef WECHAT_FACTORY_H
#define WECHAT_FACTORY_H
#include "IPaymentFactory.h"
#include "WechatPay.h"
#include "WechatRefund.h"
#include "WechatReconciliation.h"
class WechatFactory : public IPaymentFactory {
public:
std::unique_ptr<IPay> createPay() override {
return std::make_unique<WechatPay>();
}
std::unique_ptr<IRefund> createRefund() override {
return std::make_unique<WechatRefund>();
}
std::unique_ptr<IReconciliation> createReconciliation() override {
return std::make_unique<WechatReconciliation>();
}
};
#endif // WECHAT_FACTORY_H
// AlipayFactory.h(具体工厂:支付宝产品族)
#ifndef ALIPAY_FACTORY_H
#define ALIPAY_FACTORY_H
#include "IPaymentFactory.h"
#include "Alipay.h"
#include "AlipayRefund.h"
#include "AlipayReconciliation.h"
class AlipayFactory : public IPaymentFactory {
public:
std::unique_ptr<IPay> createPay() override {
return std::make_unique<Alipay>();
}
std::unique_ptr<IRefund> createRefund() override {
return std::make_unique<AlipayRefund>();
}
std::unique_ptr<IReconciliation> createReconciliation() override {
return std::make_unique<AlipayReconciliation>();
}
};
#endif // ALIPAY_FACTORY_H
3.1.5 业务模块(订单系统)
// OrderSystem.h(业务模块:只依赖抽象工厂)
#ifndef ORDER_SYSTEM_H
#define ORDER_SYSTEM_H
#include "IPaymentFactory.h"
#include <string>
class OrderSystem {
public:
// 业务逻辑:只接收抽象工厂,不关心具体产品族
void processOrder(IPaymentFactory& factory, double amount, const std::string& orderId) {
std::cout << "=== 处理订单:" << orderId << " ===" << std::endl;
// 1. 通过抽象工厂创建同一产品族的3个产品(无需关心具体是哪个产品族)
auto pay = factory.createPay();
auto refund = factory.createRefund();
auto recon = factory.createReconciliation();
// 2. 业务逻辑:支付→退款→对账
std::cout << "步骤1:" << pay->getPayName() << std::endl;
pay->pay(amount);
std::cout << "步骤2:" << refund->getRefundName() << "(退50%)" << std::endl;
refund->refund(amount * 0.5);
std::cout << "步骤3:" << recon->getReconName() << std::endl;
recon->reconcile();
}
};
#endif // ORDER_SYSTEM_H
3.1.6 新增银联产品族(无需修改老代码)
// UnionPay.h(银联支付)
#ifndef UNION_PAY_H
#define UNION_PAY_H
#include "IPay.h"
class UnionPay : public IPay {
public:
void pay(double amount) override {
std::cout << "[银联支付] 发起支付请求,金额:" << amount << "元" << std::endl;
}
std::string getPayName() const override { return "银联支付"; }
};
#endif // UNION_PAY_H
// UnionRefund.h(银联退款)
#ifndef UNION_REFUND_H
#define UNION_REFUND_H
#include "IRefund.h"
class UnionRefund : public IRefund {
public:
void refund(double amount) override {
std::cout << "[银联退款] 发起退款请求,金额:" << amount << "元" << std::endl;
}
std::string getRefundName() const override { return "银联退款"; }
};
#endif // UNION_REFUND_H
// UnionReconciliation.h(银联对账)
#ifndef UNION_RECONCILIATION_H
#define UNION_RECONCILIATION_H
#include "IReconciliation.h"
class UnionReconciliation : public IReconciliation {
public:
void reconcile() override {
std::cout << "[银联对账] 对接银联商户平台,核对今日交易流水" << std::endl;
}
std::string getReconName() const override { return "银联对账"; }
};
#endif // UNION_RECONCILIATION_H
// UnionFactory.h(银联工厂:新增产品族,无需修改老代码)
#ifndef UNION_FACTORY_H
#define UNION_FACTORY_H
#include "IPaymentFactory.h"
#include "UnionPay.h"
#include "UnionRefund.h"
#include "UnionReconciliation.h"
class UnionFactory : public IPaymentFactory {
public:
std::unique_ptr<IPay> createPay() override { return std::make_unique<UnionPay>(); }
std::unique_ptr<IRefund> createRefund() override { return std::make_unique<UnionRefund>(); }
std::unique_ptr<IReconciliation> createReconciliation() override { return std::make_unique<UnionReconciliation>(); }
};
#endif // UNION_FACTORY_H
3.1.7 主函数测试
// main.cpp
#include <iostream>
#include "OrderSystem.h"
#include "WechatFactory.h"
#include "AlipayFactory.h"
#include "UnionFactory.h"
int main() {
OrderSystem orderSystem;
// 1. 测试微信产品族
WechatFactory wechatFactory;
orderSystem.processOrder(wechatFactory, 199.9, "ORDER001");
// 2. 测试支付宝产品族(切换产品族只需换工厂)
std::cout << "\n" << std::endl;
AlipayFactory alipayFactory;
orderSystem.processOrder(alipayFactory, 299.9, "ORDER002");
// 3. 测试新增银联产品族(无需修改OrderSystem)
std::cout << "\n" << std::endl;
UnionFactory unionFactory;
orderSystem.processOrder(unionFactory, 399.9, "ORDER003");
return 0;
}
3.2 编译与运行说明
3.2.1 编译命令(GCC)
g++ -std=c++11 main.cpp WechatPay.cpp WechatRefund.cpp WechatReconciliation.cpp \
Alipay.cpp AlipayRefund.cpp AlipayReconciliation.cpp \
UnionPay.cpp UnionRefund.cpp UnionReconciliation.cpp -o payment_system
- 依赖:C++11 及以上标准(支持
std::unique_ptr和override); - 编译环境:Linux/GCC、Windows/MinGW、Mac/Clang 均可。
3.2.2 运行结果
=== 处理订单:ORDER001 ===
步骤1:微信支付
[微信支付] 发起支付请求,金额:199.9元
步骤2:微信退款(退50%)
[微信退款] 发起退款请求,金额:99.95元
步骤3:微信对账
[微信对账] 对接微信商户平台,核对今日交易流水
=== 处理订单:ORDER002 ===
步骤1:支付宝支付
[支付宝支付] 发起支付请求,金额:299.9元
步骤2:支付宝退款(退50%)
[支付宝退款] 发起退款请求,金额:149.95元
步骤3:支付宝对账
[支付宝对账] 对接支付宝商户平台,核对今日交易流水
=== 处理订单:ORDER003 ===
步骤1:银联支付
[银联支付] 发起支付请求,金额:399.9元
步骤2:银联退款(退50%)
[银联退款] 发起退款请求,金额:199.95元
步骤3:银联对账
[银联对账] 对接银联商户平台,核对今日交易流水
3.3 重构后的核心优势(对比反例)
重构后的代码完全符合抽象工厂模式,解决了反例的所有问题:
- 工厂数量精简:1 个产品族对应 1 个工厂,2 个产品族 + 新增银联 = 3 个工厂,而非 6 个,管理成本大幅降低;
- 一键切换产品族:业务模块切换产品族只需换工厂实例(如
WechatFactory→AlipayFactory),无需修改任何业务代码,符合开放封闭原则; - 产品族自动匹配:抽象工厂确保创建的产品属于同一产品族(如微信工厂只创建微信相关产品),避免业务模块配错产品的风险;
- 扩展成本低:新增产品族(如银联)只需新增 1 个具体工厂 + 对应产品,老代码(抽象工厂、业务模块)一行不动;
- 职责清晰:抽象工厂负责 “创建同一产品族的多个产品”,业务模块负责 “使用产品”,创建逻辑与业务逻辑彻底分离,代码可读性和维护性大幅提升。
四、扩展实战:抽象工厂模式的 3 个经典应用场景

抽象工厂模式的核心价值是 “切换产品族”,在 C++ 开发中,凡是需要 “整套配套产品切换” 的场景,都能发挥其优势。下面通过 3 个真实场景,展示模式的灵活性。
4.1 场景 1:UI 组件库(跨平台界面切换)
需求:开发跨平台应用,支持 Windows 和 Mac 两套 UI 组件(按钮、输入框、下拉框),可一键切换平台。
抽象工厂实现:
// ======================== 抽象产品(UI组件族)========================
// 抽象产品1:按钮
class IButton {
public:
virtual ~IButton() = default;
virtual void render() = 0; // 渲染按钮
};
// 抽象产品2:输入框
class IInput {
public:
virtual ~IInput() = default;
virtual void render() = 0; // 渲染输入框
};
// 抽象产品3:下拉框
class IDropdown {
public:
virtual ~IDropdown() = default;
virtual void render() = 0; // 渲染下拉框
};
// ======================== 具体产品(Windows UI族)========================
class WindowsButton : public IButton {
public:
void render() override { std::cout << "渲染Windows风格按钮(灰色边框,方形)" << std::endl; }
};
class WindowsInput : public IInput {
public:
void render() override { std::cout << "渲染Windows风格输入框(白色背景,黑色文字)" << std::endl; }
};
class WindowsDropdown : public IDropdown {
public:
void render() override { std::cout << "渲染Windows风格下拉框(点击展开,蓝色选中)" << std::endl; }
};
// ======================== 具体产品(Mac UI族)========================
class MacButton : public IButton {
public:
void render() override { std::cout << "渲染Mac风格按钮(无边框,圆角)" << std::endl; }
};
class MacInput : public IInput {
public:
void render() override { std::cout << "渲染Mac风格输入框(浅灰色背景,黑色文字)" << std::endl; }
};
class MacDropdown : public IDropdown {
public:
void render() override { std::cout << "渲染Mac风格下拉框(hover展开,灰色选中)" << std::endl; }
};
// ======================== 抽象工厂与具体工厂 ========================
// 抽象工厂:UI组件工厂
class IUIFactory {
public:
virtual ~IUIFactory() = default;
virtual std::unique_ptr<IButton> createButton() = 0;
virtual std::unique_ptr<IInput> createInput() = 0;
virtual std::unique_ptr<IDropdown> createDropdown() = 0;
};
// Windows UI工厂
class WindowsUIFactory : public IUIFactory {
public:
std::unique_ptr<IButton> createButton() override { return std::make_unique<WindowsButton>(); }
std::unique_ptr<IInput> createInput() override { return std::make_unique<WindowsInput>(); }
std::unique_ptr<IDropdown> createDropdown() override { return std::make_unique<WindowsDropdown>(); }
};
// Mac UI工厂
class MacUIFactory : public IUIFactory {
public:
std::unique_ptr<IButton> createButton() override { return std::make_unique<MacButton>(); }
std::unique_ptr<IInput> createInput() override { return std::make_unique<MacInput>(); }
std::unique_ptr<IDropdown> createDropdown() override { return std::make_unique<MacDropdown>(); }
};
// ======================== 业务模块:应用渲染 ========================
class App {
public:
void renderUI(IUIFactory& factory) {
std::cout << "=== 渲染应用UI ===" << std::endl;
auto button = factory.createButton();
auto input = factory.createInput();
auto dropdown = factory.createDropdown();
button->render();
input->render();
dropdown->render();
}
};
// 测试代码
int main() {
App app;
// 渲染Windows风格UI
std::cout << "【Windows平台】" << std::endl;
WindowsUIFactory windowsFactory;
app.renderUI(windowsFactory);
// 一键切换到Mac风格UI
std::cout << "\n【Mac平台】" << std::endl;
MacUIFactory macFactory;
app.renderUI(macFactory);
return 0;
}
运行结果:
【Windows平台】
=== 渲染应用UI ===
渲染Windows风格按钮(灰色边框,方形)
渲染Windows风格输入框(白色背景,黑色文字)
渲染Windows风格下拉框(点击展开,蓝色选中)
【Mac平台】
=== 渲染应用UI ===
渲染Mac风格按钮(无边框,圆角)
渲染Mac风格输入框(浅灰色背景,黑色文字)
渲染Mac风格下拉框(hover展开,灰色选中)
优势:新增 Linux 平台 UI 时,只需新增LinuxUIFactory和对应的 3 个组件,应用渲染逻辑App完全不用改,实现 “一键切换平台 UI”。
4.2 场景 2:数据库访问层(多数据库切换)
需求:支持 MySQL 和 PostgreSQL 两种数据库,每种数据库包含连接、查询、事务 3 个配套操作,可动态切换数据库。
抽象工厂实现:
// ======================== 抽象产品(数据库操作族)========================
// 抽象产品1:数据库连接
class IDbConnection {
public:
virtual ~IDbConnection() = default;
virtual void connect() = 0; // 建立连接
};
// 抽象产品2:数据库查询
class IDbQuery {
public:
virtual ~IDbQuery() = default;
virtual void execute(const std::string& sql) = 0; // 执行查询
};
// 抽象产品3:数据库事务
class IDbTransaction {
public:
virtual ~IDbTransaction() = default;
virtual void begin() = 0; // 开始事务
virtual void commit() = 0; // 提交事务
virtual void rollback() = 0; // 回滚事务
};
// ======================== 具体产品(MySQL族)========================
class MysqlConnection : public IDbConnection {
public:
void connect() override { std::cout << "MySQL:建立数据库连接(mysql_real_connect)" << std::endl; }
};
class MysqlQuery : public IDbQuery {
public:
void execute(const std::string& sql) override {
std::cout << "MySQL:执行SQL:" << sql << "(mysql_query)" << std::endl;
}
};
class MysqlTransaction : public IDbTransaction {
public:
void begin() override { std::cout << "MySQL:开始事务(SET AUTOCOMMIT=0)" << std::endl; }
void commit() override { std::cout << "MySQL:提交事务(COMMIT)" << std::endl; }
void rollback() override { std::cout << "MySQL:回滚事务(ROLLBACK)" << std::endl; }
};
// ======================== 具体产品(PostgreSQL族)========================
class PgConnection : public IDbConnection {
public:
void connect() override { std::cout << "PostgreSQL:建立数据库连接(PQconnectdb)" << std::endl; }
};
class PgQuery : public IDbQuery {
public:
void execute(const std::string& sql) override {
std::cout << "PostgreSQL:执行SQL:" << sql << "(PQexec)" << std::endl;
}
};
class PgTransaction : public IDbTransaction {
public:
void begin() override { std::cout << "PostgreSQL:开始事务(BEGIN)" << std::endl; }
void commit() override { std::cout << "PostgreSQL:提交事务(COMMIT)" << std::endl; }
void rollback() override { std::cout << "PostgreSQL:回滚事务(ROLLBACK)" << std::endl; }
};
// ======================== 抽象工厂与具体工厂 ========================
class IDbFactory {
public:
virtual ~IDbFactory() = default;
virtual std::unique_ptr<IDbConnection> createConnection() = 0;
virtual std::unique_ptr<IDbQuery> createQuery() = 0;
virtual std::unique_ptr<IDbTransaction> createTransaction() = 0;
};
class MysqlFactory : public IDbFactory {
public:
std::unique_ptr<IDbConnection> createConnection() override { return std::make_unique<MysqlConnection>(); }
std::unique_ptr<IDbQuery> createQuery() override { return std::make_unique<MysqlQuery>(); }
std::unique_ptr<IDbTransaction> createTransaction() override { return std::make_unique<MysqlTransaction>(); }
};
class PgFactory : public IDbFactory {
public:
std::unique_ptr<IDbConnection> createConnection() override { return std::make_unique<PgConnection>(); }
std::unique_ptr<IDbQuery> createQuery() override { return std::make_unique<PgQuery>(); }
std::unique_ptr<IDbTransaction> createTransaction() override { return std::make_unique<PgTransaction>(); }
};
// ======================== 业务模块:数据访问服务 ========================
class DataService {
public:
void processData(IDbFactory& factory) {
std::cout << "=== 处理数据 ===" << std::endl;
// 1. 创建数据库操作族
auto conn = factory.createConnection();
auto query = factory.createQuery();
auto tx = factory.createTransaction();
// 2. 业务逻辑:连接→事务→查询→提交
conn->connect();
tx->begin();
query->execute("SELECT * FROM users WHERE id=1001");
tx->commit();
}
};
// 测试代码
int main() {
DataService dataService;
// 使用MySQL
std::cout << "【使用MySQL】" << std::endl;
MysqlFactory mysqlFactory;
dataService.processData(mysqlFactory);
// 切换到PostgreSQL
std::cout << "\n【使用PostgreSQL】" << std::endl;
PgFactory pgFactory;
dataService.processData(pgFactory);
return 0;
}
运行结果:
【使用MySQL】
=== 处理数据 ===
MySQL:建立数据库连接(mysql_real_connect)
MySQL:开始事务(SET AUTOCOMMIT=0)
MySQL:执行SQL:SELECT * FROM users WHERE id=1001(mysql_query)
MySQL:提交事务(COMMIT)
【使用PostgreSQL】
=== 处理数据 ===
PostgreSQL:建立数据库连接(PQconnectdb)
PostgreSQL:开始事务(BEGIN)
PostgreSQL:执行SQL:SELECT * FROM users WHERE id=1001(PQexec)
PostgreSQL:提交事务(COMMIT)
优势:业务模块无需关心数据库的具体实现(如 MySQL 的mysql_query和 PostgreSQL 的PQexec),切换数据库只需换工厂,实现 “数据库无关” 的设计。
4.3 场景 3:游戏装备系统(职业装备切换)
需求:游戏支持战士和法师两种职业,每种职业有配套的武器、防具、技能,切换职业时自动切换整套装备。
抽象工厂实现:
// ======================== 抽象产品(装备族)========================
// 抽象产品1:武器
class IWeapon {
public:
virtual ~IWeapon() = default;
virtual void attack() = 0; // 武器攻击
};
// 抽象产品2:防具
class IArmor {
public:
virtual ~IArmor() = default;
virtual void defend() = 0; // 防具防御
};
// 抽象产品3:技能
class ISkill {
public:
virtual ~ISkill() = default;
virtual void cast() = 0; // 释放技能
};
// ======================== 具体产品(战士装备族)========================
class WarriorSword : public IWeapon {
public:
void attack() override { std::cout << "战士武器:青铜剑,造成100点物理伤害" << std::endl; }
};
class WarriorShield : public IArmor {
public:
void defend() override { std::cout << "战士防具:铁盾,减免50点物理伤害" << std::endl; }
};
class WarriorSlash : public ISkill {
public:
void cast() override { std::cout << "战士技能:横斩,对前方敌人造成150点物理伤害" << std::endl; }
};
// ======================== 具体产品(法师装备族)========================
class MageWand : public IWeapon {
public:
void attack() override { std::cout << "法师武器:魔法杖,造成80点魔法伤害" << std::endl; }
};
class MageRobe : public IArmor {
public:
void defend() override { std::cout << "法师防具:魔法袍,减免30点魔法伤害" << std::endl; }
};
class MageFireball : public ISkill {
public:
void cast() override { std::cout << "法师技能:火球术,对单个敌人造成200点魔法伤害" << std::endl; }
};
// ======================== 抽象工厂与具体工厂 ========================
class IEquipmentFactory {
public:
virtual ~IEquipmentFactory() = default;
virtual std::unique_ptr<IWeapon> createWeapon() = 0;
virtual std::unique_ptr<IArmor> createArmor() = 0;
virtual std::unique_ptr<ISkill> createSkill() = 0;
};
class WarriorFactory : public IEquipmentFactory {
public:
std::unique_ptr<IWeapon> createWeapon() override { return std::make_unique<WarriorSword>(); }
std::unique_ptr<IArmor> createArmor() override { return std::make_unique<WarriorShield>(); }
std::unique_ptr<ISkill> createSkill() override { return std::make_unique<WarriorSlash>(); }
};
class MageFactory : public IEquipmentFactory {
public:
std::unique_ptr<IWeapon> createWeapon() override { return std::make_unique<MageWand>(); }
std::unique_ptr<IArmor> createArmor() override { return std::make_unique<MageRobe>(); }
std::unique_ptr<ISkill> createSkill() override { return std::make_unique<MageFireball>(); }
};
// ======================== 业务模块:游戏角色 ========================
class GameCharacter {
public:
void equip(IEquipmentFactory& factory, const std::string& roleName) {
std::cout << "=== " << roleName << "装备整套装备 ===" << std::endl;
auto weapon = factory.createWeapon();
auto armor = factory.createArmor();
auto skill = factory.createSkill();
weapon->attack();
armor->defend();
skill->cast();
}
};
// 测试代码
int main() {
GameCharacter character;
// 战士装备
WarriorFactory warriorFactory;
character.equip(warriorFactory, "战士");
// 切换法师装备
std::cout << "\n" << std::endl;
MageFactory mageFactory;
character.equip(mageFactory, "法师");
return 0;
}
运行结果:
=== 战士装备整套装备 ===
战士武器:青铜剑,造成100点物理伤害
战士防具:铁盾,减免50点物理伤害
战士技能:横斩,对前方敌人造成150点物理伤害
=== 法师装备整套装备 ===
法师武器:魔法杖,造成80点魔法伤害
法师防具:魔法袍,减免30点魔法伤害
法师技能:火球术,对单个敌人造成200点魔法伤害
优势:新增 “牧师” 职业时,只需新增PriestFactory和对应的武器、防具、技能,游戏角色逻辑完全不变,实现 “职业一键切换装备”。
五、C++ 实战避坑指南:抽象工厂模式的 5 个常见误区

抽象工厂模式虽然强大,但在实际应用中容易因理解偏差导致 “过度设计” 或 “使用不当”。下面列出 5 个典型误区及避坑方案。
误区 1:混淆 “产品族” 和 “产品等级结构”
比如把 “微信支付” 和 “支付宝支付” 当成产品族(实际是产品等级结构),把 “支付” 和 “退款” 当成产品等级结构(实际是产品族)—— 导致抽象工厂接口设计错误,无法实现产品族切换。
避坑方案:
- 产品族:同一场景下的 “配套产品”(如支付 + 退款 + 对账),必须一起使用;
- 产品等级结构:不同场景下的 “替代产品”(如微信支付 + 支付宝支付),只能选一个使用;
- 定义抽象工厂前,先明确 “哪些产品是配套的”,再设计抽象工厂的创建方法。
误区 2:抽象工厂接口过于臃肿
比如抽象工厂包含createPay()、createRefund()、createReconciliation()、createLog()、createConfig()等十几个方法,涵盖不相关的产品,导致具体工厂被迫实现不需要的方法。
避坑方案:
- 遵循 “接口单一职责”:一个抽象工厂只负责一个产品族的创建,不包含无关产品;
- 若有多个不相关的产品族,拆分多个抽象工厂(如
IPaymentFactory负责支付族,ILogFactory负责日志族),避免 “万能工厂”。
误区 3:滥用抽象工厂模式,简单场景过度设计
比如只是创建单个产品(如仅支付功能),没有产品族,却强行用抽象工厂模式,导致代码复杂度增加(抽象工厂 + 具体工厂 + 抽象产品 + 具体产品)。
避坑方案:
- 单个产品替代场景:用工厂方法模式;
- 多产品族切换场景:用抽象工厂模式;
- 简单对象(无复杂创建逻辑):直接
new,无需设计模式。
误区 4:新增产品等级结构时修改抽象工厂
比如抽象工厂IPaymentFactory包含createPay()、createRefund(),新增产品等级结构 “对账明细导出” 时,直接在抽象工厂中加createReconExport()—— 导致所有具体工厂都要同步修改,违反开放封闭原则。
避坑方案:
- 抽象工厂模式适合 “产品族稳定,产品等级结构不新增” 的场景;
- 若必须新增产品等级结构,可通过 “扩展抽象工厂” 实现(如
IPaymentFactoryV2继承IPaymentFactory,新增createReconExport()),避免修改原有抽象工厂。
误区 5:忽视 C++ 的智能指针和依赖注入
比如抽象工厂的创建方法返回原始指针,导致内存泄漏;业务模块直接new具体工厂,硬编码产品族,无法动态切换。
避坑方案:
- 用
std::unique_ptr/std::shared_ptr管理产品和工厂的生命周期,避免内存泄漏; - 业务模块通过 “依赖注入” 获取抽象工厂(如构造函数传入),不硬编码具体工厂,支持动态切换产品族。
六、总结:抽象工厂模式的核心与实战建议

6.1 核心要点提炼
- 核心思想:抽象工厂负责创建同一产品族的多个配套产品,业务模块依赖抽象工厂,实现产品族一键切换;
- 关键概念:产品族(配套使用)vs 产品等级结构(相互替代),这是与工厂方法模式的核心区别;
- 4 个角色:抽象产品(产品等级结构)、具体产品(产品族成员)、抽象工厂(产品族创建接口)、具体工厂(产品族创建实现);
- 核心价值:解耦产品族创建与业务逻辑,支持整套产品切换,符合开放封闭原则;
- 适用场景:跨平台 UI、多数据库切换、游戏职业装备、配套工具集等需要 “整套产品切换” 的场景。
6.2 C++ 实战建议
-
抽象设计:
- 抽象产品用纯虚类定义,包含核心业务方法,不包含具体实现;
- 抽象工厂只定义同一产品族的创建方法,方法名统一(如
createXxx()),返回抽象产品的智能指针; - 具体工厂实现抽象工厂,确保创建的产品属于同一产品族,不混合其他产品族的产品。
-
具体实现:
- 产品需要初始化参数时,通过具体工厂的构造函数传递(如
FileLoggerFactory接收日志路径); - 产品族的创建逻辑封装在具体工厂中,业务模块无需关心产品的创建细节(如 SDK 调用、配置初始化)。
- 产品需要初始化参数时,通过具体工厂的构造函数传递(如
-
业务调用:
- 业务模块只依赖抽象工厂,不依赖具体工厂和具体产品;
- 通过依赖注入获取抽象工厂,支持动态切换产品族(如从配置文件读取产品族类型,创建对应工厂)。
-
与其他模式结合:
- 结合单例模式:无状态的具体工厂设计为单例(如
WechatFactory),避免重复创建; - 结合依赖注入框架:大型项目中,用依赖注入框架(如 Boost.DI)管理工厂的创建和注入;
- 结合原型模式:产品创建成本高时,工厂先创建原型,再通过克隆生成产品,提升效率。
- 结合单例模式:无状态的具体工厂设计为单例(如
6.3 最后一句话
抽象工厂模式的本质,是 “用抽象隔离产品族的创建变化”。它不只是工厂方法模式的 “升级版”,而是针对 “多产品族切换” 的专属解决方案 —— 当你发现工厂方法模式导致工厂泛滥、产品族管理混乱时,抽象工厂模式就是最优解。
记住:设计模式的价值不是 “炫技”,而是 “解决实际问题”。选择设计模式时,先明确场景(是单个产品替代,还是多产品族切换),再选择合适的模式,避免为了模式而模式。
5986

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



