一、创造型模式

1.工厂方法模式(2025年8月5日)

工厂方法模式(Factory Method Pattern),属于创造型模式,旨在统一定义创造对象接口。
可以通俗的理解成,在一般情况下不同的东西来源于不同的地方。现在统一了这个地方(factory),客户只需要根据自身需求去访问这个地方就能获得相对应的东西。其他逻辑无需改变。

优缺点

优点:

  • **解耦了对象的创建和使用:**调用方只需要考虑如何使用new出来的对象,不需要考虑他是怎么new出来的全部交给工厂来解决。
  • 符合开闭原则,易于扩展: 当需要新加产品时只需要在工厂新加一个对应类和实现方法就行。在用户使用的地方无需修改
  • 提高了代码的复用性和可维护性: 创建逻辑全部集中在工厂,避免重复造轮子。维护成本低。

缺点

  • 类的种类增多
  • 系统变得复杂
  • 可能会过度设计

总而言之如果在维护一个后期看起来就会添加许多其他东西可以使用工厂模式,例如手机的支付方式。目前有银行卡,微信,支付宝。未来如果要添加其他的支付方式就可有使用这种设计模式。

2.参考deepseek给出的支付方式样例

定义支付接口

1
2
3
4
5
// 支付接口 - 抽象产品
public interface Payment {
void pay(double amount); // 支付方法
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
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// 支付宝支付 - 具体产品
public class Alipay implements Payment {
@Override
public void pay(double amount) {
System.out.println("使用支付宝支付: " + amount + "元");
// 实际的支付宝支付逻辑...
}

@Override
public void refund(double amount) {
System.out.println("支付宝退款: " + amount + "元");
// 实际的支付宝退款逻辑...
}
}

// 微信支付 - 具体产品
public class WechatPay implements Payment {
@Override
public void pay(double amount) {
System.out.println("使用微信支付: " + amount + "元");
// 实际的微信支付逻辑...
}

@Override
public void refund(double amount) {
System.out.println("微信退款: " + amount + "元");
// 实际的微信退款逻辑...
}
}

// 银行卡支付 - 具体产品
public class BankCardPay implements Payment {
@Override
public void pay(double amount) {
System.out.println("使用银行卡支付: " + amount + "元");
// 实际的银行卡支付逻辑...
}

@Override
public void refund(double amount) {
System.out.println("银行卡退款: " + amount + "元");
// 实际的银行卡退款逻辑...
}
}

定义支付工厂接口

1
2
3
4
// 支付工厂接口 - 抽象工厂
public interface PaymentFactory {
Payment createPayment(); // 创建支付方式
}

实现具体支付工厂

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 AlipayFactory implements PaymentFactory {
@Override
public Payment createPayment() {
return new Alipay();
}
}

// 微信支付工厂
public class WechatPayFactory implements PaymentFactory {
@Override
public Payment createPayment() {
return new WechatPay();
}
}

// 银行卡支付工厂
public class BankCardPayFactory implements PaymentFactory {
@Override
public Payment createPayment() {
return new BankCardPay();
}
}

客户端使用

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
public class PaymentClient {
public static void main(String[] args) {
// 模拟用户选择的支付方式
String paymentMethod = "wechat"; // 可以从配置或用户输入获取

// 根据用户选择创建对应的支付工厂
PaymentFactory factory = getPaymentFactory(paymentMethod);

// 使用工厂创建支付实例
Payment payment = factory.createPayment();

// 执行支付
payment.pay(100.00);

// 如果需要退款
payment.refund(50.00);
}

// 简单工厂方法,根据类型返回具体工厂
private static PaymentFactory getPaymentFactory(String type) {
switch (type.toLowerCase()) {
case "alipay":
return new AlipayFactory();
case "wechat":
return new WechatPayFactory();
case "bankcard":
return new BankCardPayFactory();
default:
throw new IllegalArgumentException("不支持的支付方式: " + type);
}
}
}

具体流程

首先各个产品(支付宝,微信)都要实现对应的payment方法。这是产品的功能。

从工厂中根据想要的产品去找到对应的factory。每个factory都实现了PaymentFactory。所以可以从PaymentFactory中的Payment方法调用返回对应的产品。

3.开源框架中的使用

JDK中的Calendar.getInstance(): 会根据不同地区,语言环境去返回不同的子类实例。

spring中的BeanFactory: 创造bean时会根据不同的类型进行创建。BeanFactory的创建有三种方式:XML配置方式、java方式和注解配置方式。
spring 最顶级接口 beanfactory详解-CSDN博客

4.实践

文件解析模块:根据上传不同的文件类型chuangj对应的解析器示例和入口

创建产品抽象类

upload successful

创建产品具体

upload successful

创建抽象工厂

1
2
3
4
public interface Factory {
FileProduct doFileProduct();
}

实现各个工厂

upload successful

启动

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
35
public class Main {
public static void main(String[] args) {
String fileType = "JSON";
Factory factory = getFactory(fileType);
FileProduct fileProduct = factory.doFileProduct();
fileProduct.doJieXi();

fileType="Excel";
factory=getFactory(fileType);
fileProduct = factory.doFileProduct();
fileProduct.doJieXi();


fileType = "CSV";
factory=getFactory(fileType);
fileProduct = factory.doFileProduct();
fileProduct.doJieXi();

fileType = "XML";
factory = getFactory(fileType);
fileProduct = factory.doFileProduct();
fileProduct.doJieXi();
}

public static Factory getFactory(String fileType){
if(fileType.equals("JSON")){
return new JSONFactoryImpl();
}else if(fileType.equals("Excel")){
return new ExcelFactoryImpl();
}else if(fileType.equals("CSV")){
return new CSVFactoryImpl();
}
throw new RuntimeException("不支持此类型");
}
}

结果

upload successful

总结

工厂方法模式具有的角色和职责:

抽象产品(Product):定义产品的公共接口,是所有具体产品的父类。

具体产品(ConcreteProduct):实现了抽象产品接口,表示某种具体的产品。

抽象工厂(Factory):定义了一个返回产品对象的方法(一般是一个抽象方法)。

具体工厂(ConcreteFactory):实现了抽象工厂中的创建产品的方法,生成具体的产品实例。