设计模式|工厂方法模式

核心思想

工厂方法本质是为了解决 **“对象创建” 与 “业务使用” 的强耦合问题 **,并通过 “抽象化” 让系统更灵活、更易扩展

工厂方法模式的核心思路,可以总结为 “定义一个创建对象的抽象接口(工厂接口),让具体的对象创建工作由其子类(具体工厂)完成,业务层只依赖抽象工厂和抽象产品,不依赖具体实现”

我们可以用一个 “分工比喻” 理解:

  • 不使用工厂方法的模式:“厨师(业务层)既要买菜(创建对象),又要做菜(业务逻辑)”;
  • 工厂方法模式:“厨师(业务层)只负责做菜,买菜的工作交给专门的‘采购工厂’(具体工厂),厨师只需要告诉工厂‘要什么菜’(抽象产品),不用管‘菜从哪来’(具体实现)”。

代码实现

原始代码实现

在没有使用工厂方法时,我们通常会直接用 new 关键字创建对象,比如一个电商系统中创建 “支付方式” 的场景:

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
27
28
29
30
31
32
33
34
// 业务代码中直接new具体支付对象
public class OrderService {
// 处理订单支付
public void pay(String payType, double amount) {
Payment payment;
// 直接根据类型new具体实现类
if ("WECHAT".equals(payType)) {
payment = new WechatPayment(); // 耦合WechatPayment
} else if ("ALIPAY".equals(payType)) {
payment = new AlipayPayment(); // 耦合AlipayPayment
} else {
throw new RuntimeException("不支持的支付方式");
}
// 使用支付对象完成业务
payment.processPayment(amount);
}
}

// 支付接口与具体实现
interface Payment {
void processPayment(double amount);
}
class WechatPayment implements Payment {
@Override
public void processPayment(double amount) {
System.out.println("微信支付:" + amount + "元");
}
}
class AlipayPayment implements Payment {
@Override
public void processPayment(double amount) {
System.out.println("支付宝支付:" + amount + "元");
}
}
1
2
3
4
5
6
7
8
9
public class Client {
public static void main(String[] args) {
OrderService orderService = new OrderService();
orderService.pay("WECHAT", 3.3);
System.out.println("Switching payment ...");
orderService.pay("ALIPAY", 3.3);
}
}

这段代码其实也不会很屎,甚至还知道要抽取通用的逻辑processPayment来进行处理

但是还是将实际支付逻辑对象的创建,与对象支付逻辑的使用 耦合在了一起

我们可以使用工厂方法设计模式来解决这一问题

最佳实践

“产品抽象化”

定义统一的抽象产品接口(这里的产品、也就是被创建对象的类)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public interface Payment {
void processPayment(double amount); // 通用支付方法
}

public class AlipayPayment implements Payment{
@Override
public void processPayment(double amt) {
System.out.println("Paid " + amt + "$ with alipay");
}
}

public class WechatPayment implements Payment{
@Override
public void processPayment(double amt) {
System.out.println("Paid " + amt + "$ with wechat");
}
}

“工厂抽象化”

定义创建对象的抽象工厂接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public interface PaymentFactory {
Payment createPayment(); // 抽象的“创建产品”方法
}

public class AlipayPaymentFactory implements PaymentFactory{
@Override
public Payment createPayment() {
return new AlipayPayment();
}
}

public class WechatPaymentFactory implements PaymentFactory{
@Override
public Payment createPayment() {
return new WechatPayment();
}
}

业务层依赖抽象,脱离具体实现

将创建于使用解耦,业务层只负责使用,创建交由工厂的实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class OrderServiceRefactored {

private PaymentFactory paymentFactory;

public OrderServiceRefactored(PaymentFactory paymentFactory) {
this.paymentFactory = paymentFactory;
}

public void setPaymentFactory(PaymentFactory paymentFactory) {
this.paymentFactory = paymentFactory;
}

public void payOrder(double amt) {
Payment payment = this.paymentFactory.createPayment();
payment.processPayment(amt);
}

}

模拟客户端测试

由于原先的代码中有根据 payType 枚举参数进行判断的逻辑,而这一段逻辑主要是用来决定对象的创建的

而对象的创建本质上和 OrderService 无关,是 Factory 需要做的事情,因此我们可以将其从 OrderService 中抽离出来

1
2
3
4
5
6
7
8
9
10
11
12
13
public class PaymentFactorySelector {
// 根据支付类型字符串获取对应的工厂
public static PaymentFactory getFactory(String payType) {
if ("WECHAT".equals(payType)) {
return new WechatPaymentFactory();
} else if ("ALIPAY".equals(payType)) {
return new AlipayPaymentFactory();
} else {
throw new IllegalArgumentException("不支持的支付方式: " + payType);
}
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class FactoryMethodClientRefactored {

public static void main(String[] args) {
PaymentFactory factory = PaymentFactorySelector.getFactory("WECHAT");
OrderServiceRefactored orderService = new OrderServiceRefactored(factory);
orderService.payOrder(3.3);

System.out.println("Switching payment ...");

PaymentFactory alipayFactory = PaymentFactorySelector.getFactory("ALIPAY");
//切换payment
orderService.setPaymentFactory(alipayFactory);
orderService.payOrder(3.3);
}
}

总结

工厂方法模式的核心思想,本质是对依赖倒置原则(依赖抽象,不依赖具体)和单一职责原则(一个类只做一件事)的落地,是将业务逻辑类中关联业务逻辑处理对象的创建 与 使用进行解耦

业务类只专注于处理具体业务逻辑,不再进行相关对象的创建

对象的创建统一在工厂接口的实现类中各自决定

简单来说,工厂方法设计模式就是 将对象的创建权交给专门的‘抽象工厂’,业务层只关心‘要什么产品’(通过抽象工厂拿抽象产品),不关心‘产品怎么造’(具体工厂实现),从而实现‘创建’与‘使用’的解耦,让系统易扩展、易维护


设计模式|工厂方法模式
http://example.com/2025/09/01/设计模式-工厂方法模式/
作者
Noctis64
发布于
2025年9月1日
许可协议