问题场景
假设需要实现支付功能,支持多种支付方式(支付宝、微信、银行卡)。传统实现会使用多重 if-else 判断支付类型,导致代码臃肿且违反开闭原则。
// 传统实现(存在隐患)
public Payment createPayment(String type) {
if ("alipay".equals(type)) {
return new Alipay();
} else if ("wechat".equals(type)) {
return new WechatPay();
} else if ("bank".equals(type)) {
return new BankPay();
} else {
throw new IllegalArgumentException("Unsupported payment type");
}
}优化方案:工厂 + 策略模式
1. 策略接口与实现
// 支付策略接口
public interface Payment {
void pay(BigDecimal amount);
}
// 支付宝支付
public class Alipay implements Payment {
@Override
public void pay(BigDecimal amount) {
System.out.println("支付宝支付:" + amount);
}
}
// 微信支付
public class WechatPay implements Payment {
@Override
public void pay(BigDecimal amount) {
System.out.println("微信支付:" + amount);
}
}
// 银行卡支付
public class BankPay implements Payment {
@Override
public void pay(BigDecimal amount) {
System.out.println("银行卡支付:" + amount);
}
}2. 工厂类(核心优化)
import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;
public class PaymentFactory {
// 支付类型与构造方法的映射
private static final Map<String, Supplier<Payment>> PAYMENT_MAP = new HashMap<>();
// 初始化注册支付方式(符合开闭原则)
static {
PAYMENT_MAP.put("alipay", Alipay::new);
PAYMENT_MAP.put("wechat", WechatPay::new);
PAYMENT_MAP.put("bank", BankPay::new);
}
// 获取支付实例
public static Payment getPayment(String type) {
Supplier<Payment> paymentSupplier = PAYMENT_MAP.get(type);
if (paymentSupplier == null) {
throw new IllegalArgumentException("不支持的支付类型: " + type);
}
return paymentSupplier.get();
}
// 动态注册新支付方式(无需修改工厂代码)
public static void registerPayment(String type, Supplier<Payment> supplier) {
PAYMENT_MAP.put(type, supplier);
}
}3. 客户端调用
public class Client {
public static void main(String[] args) {
// 使用标准支付
Payment alipay = PaymentFactory.getPayment("alipay");
alipay.pay(new BigDecimal("100.50"));
// 使用新支付方式(无需修改工厂)
PaymentFactory.registerPayment("crypto", CryptoPay::new);
Payment crypto = PaymentFactory.getPayment("crypto");
crypto.pay(new BigDecimal("0.5"));
}
}
// 新增的加密货币支付(符合开闭原则)
class CryptoPay implements Payment {
@Override
public void pay(BigDecimal amount) {
System.out.println("加密货币支付:" + amount + " BTC");
}
}方案优势
- 消除条件判断:用 Map 替代 if-else 分支
- 开闭原则:新增支付方式只需注册,无需修改工厂
- 解耦:客户端与具体支付实现解耦
- 可扩展性:支持动态注册新策略
- 代码简洁:工厂类职责单一,逻辑清晰
类图
适用场景
- 需要根据不同条件执行不同算法
- 系统需要支持多种同类策略
- 存在频繁增加新策略的需求
- 需要消除复杂的条件分支语句
关键点:工厂负责对象创建,策略封装算法逻辑,两者结合实现创建与执行的解耦。通过注册机制支持动态扩展,彻底消除 if-else 分支判断。