设计模式-07-创建型-抽象工厂模式

🏗️ 抽象工厂模式(Abstract Factory Pattern)

✅ 定义

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

🧠 换句话说:

  • 如果你有多个“产品”,它们属于同一个产品族
  • 你希望通过一个“工厂”一次性创建这一整组产品
  • 并且这些产品之间可以相互配合使用

这时候就需要:抽象工厂模式


🧾 举个支付系统的例子(产品族)

你现在开发一个支付平台,支持多种支付渠道,每种渠道不仅要有:

  • 支付功能(IPay)
  • 还要有 退款功能(IRefund)

它们必须成对出现,不允许混搭。

比如:

  • 使用微信支付 → 必须配合微信退款
  • 使用支付宝支付 → 必须配合支付宝退款

于是我们有两个产品族接口:

产品 接口名 实现类(举例)
支付功能 IPay WeChatPay、AliPay
退款功能 IRefund WeChatRefund、AliRefund

你希望调用时只要一句话:

1
2
3
PayFactory factory = new WeChatFactory();
factory.createPay().pay(100);
factory.createRefund().refund(100);

👨‍💻 Java 代码实现(抽象工厂模式)

🧩 第一步:定义两个产品接口(抽象产品)

1
2
3
4
5
6
7
public interface IPay {
void pay(double amount);
}

public interface IRefund {
void refund(double amount);
}

🧩 第二步:实现具体产品(微信和支付宝)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class WeChatPay implements IPay {
public void pay(double amount) {
System.out.println("微信支付:" + amount + " 元");
}
}

public class WeChatRefund implements IRefund {
public void refund(double amount) {
System.out.println("微信退款:" + amount + " 元");
}
}

public class AliPay implements IPay {
public void pay(double amount) {
System.out.println("支付宝支付:" + amount + " 元");
}
}

public class AliRefund implements IRefund {
public void refund(double amount) {
System.out.println("支付宝退款:" + amount + " 元");
}
}

🏭 第三步:定义抽象工厂接口(创建产品族)

1
2
3
4
public interface PayFactory {
IPay createPay();
IRefund createRefund();
}

🏭 第四步:具体工厂(每种渠道对应一个工厂)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class WeChatFactory implements PayFactory {
public IPay createPay() {
return new WeChatPay();
}

public IRefund createRefund() {
return new WeChatRefund();
}
}

public class AliFactory implements PayFactory {
public IPay createPay() {
return new AliPay();
}

public IRefund createRefund() {
return new AliRefund();
}
}

🧪 第五步:客户端使用

1
2
3
4
5
6
7
8
9
10
11
public class PayClient {
public static void main(String[] args) {
PayFactory factory = new WeChatFactory();
factory.createPay().pay(88.0);
factory.createRefund().refund(88.0);

factory = new AliFactory();
factory.createPay().pay(199.0);
factory.createRefund().refund(199.0);
}
}

📌 类图结构(文字描述)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
          ┌──────────────────┐
│ PayFactory 接口 │ <─── 抽象工厂(定义多个创建方法)
└───┬─────────┬────┘
│ │
┌─────────▼───┐ ┌───▼──────────┐
│ WeChatFactory │ │ AliPayFactory │ <─── 具体工厂
└──────┬──────┘ └──┬───────────┘
│ │
┌────▼──────┐ ┌──▼────────┐
│ createPay() │ │ createRefund() │ <─── 一组产品方法
└──────┬────┘ └──────┬────┘
│ │
┌─────▼─────┐ ┌─▼──────┐
│ IPay 接口 │ │ IRefund 接口│
└─────▲─────┘ └─────▲──┘
│ │
┌───────▼─────┐ ┌──▼───────┐
│ WeChatPay │ │ WeChatRefund │ <─── 具体产品
└─────────────┘ └──────────┘



┌────────┴─────┐
│ Client │ <─── 使用者选择具体工厂,一次性创建一组产品
└──────────────┘


✅ 总结一句话:

抽象工厂模式用于创建“产品族”,即多个相关产品组成的一组,客户端只需选择哪个“工厂”,就能一次获得对应的整组产品,互相配合使用。


🧠 抽象工厂适用场景:

适用情境 示例
多个产品需要一起使用,组合成产品族 支付 + 退款、UI按钮 + 输入框
产品族切换频繁 国际版 vs 国内版组件
客户端不关心产品创建的细节 统一通过工厂创建、屏蔽实现差异

✅ 三个工厂模式 对比总结:

维度 简单工厂模式 Simple Factory 工厂方法模式 Factory Method 抽象工厂模式 Abstract Factory
✅ 核心思想 一个工厂类,根据参数创建不同产品 每种产品对应一个工厂类 一个工厂创建一组相关产品(产品族)
🧠 面向设计 面向“对象选择”(用 if/switch) 面向“子类扩展” 面向“产品族”的整体创建
📦 产品结构 一个产品等级结构 一个产品等级结构 多个产品等级结构组成产品族
🏗 工厂数量 1 个 每个产品一个工厂类 每个产品族一个工厂类
➕ 扩展方式 if/switch 添加新工厂类,实现接口 添加新产品族工厂,实现所有抽象方法
❌ 缺点 不符合开闭原则 工厂类增多,结构复杂 扩展新的产品等级结构困难
✅ 优点 简单、集中、易用 满足开闭原则、结构清晰 统一创建产品族、产品之间一致性强
🔍 使用场景 产品少,变化少 产品经常扩展 多个产品组合必须一起工作

📌 支付场景举例对比:

模式 创建方法调用 支持内容
简单工厂 SimplePayFactory.create("wechat") 只能创建 IPay
工厂方法 new WeChatPayFactory().createPay() 每个支付方式一个工厂
抽象工厂 new WeChatFactory().createPay().createRefund() 创建一个支付+退款产品组合
作者

bufx

发布于

2025-06-22

更新于

2025-07-23

许可协议