Fork me on GitHub

简单工厂模式+策略模式重构if

背景

“付款方式越来越多”的场景,其本质是——行为变化越来越多,而你不想每加一种方式就改一堆代码。
这类问题,最佳思路是使用“封装变化”的设计模式。

⛔ 不推荐的方式:

if/else 或 switch 写死在业务逻辑里:

if (type.equals("wechat")) {
    // do wechat pay
} else if (type.equals("alipay")) {
    // do alipay pay
}

这会让你代码像牛皮癣一样蔓延,维护困难,未来某天新增一种方式还得改老代码——违背开闭原则。

✅ 策略模式(Strategy Pattern)——首选

interface PaymentStrategy {
    void pay(double amount);
}

class WeChatPay implements PaymentStrategy {
    public void pay(double amount) {
        // 微信支付逻辑
    }
}

class AliPay implements PaymentStrategy {
    public void pay(double amount) {
        // 支付宝支付逻辑
    }
}

// 使用者(上下文)
class PaymentContext {
    private PaymentStrategy strategy;
    
    public PaymentContext(PaymentStrategy strategy) {
        this.strategy = strategy;
    }

    public void execute(double amount) {
        strategy.pay(amount);
    }
}

✅ 简单工厂模式 + 策略模式 —— 实用搭配

/*
 * 示例:使用策略模式 + 简单工厂管理多种请款方式
 * 作者:秋先生
 */

// 统一支付策略接口
public interface PaymentStrategy {
    void pay(double amount);
}

// 具体策略:微信支付
public class WeChatPay implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("使用微信支付:" + amount + " 元");
    }
}

// 具体策略:支付宝支付
public class AliPay implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("使用支付宝支付:" + amount + " 元");
    }
}

// 具体策略:银行卡支付
public class BankCardPay implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("使用银行卡支付:" + amount + " 元");
    }
}

// 支付策略上下文,用来调用具体策略
public class PaymentContext {
    private final PaymentStrategy strategy;

    public PaymentContext(PaymentStrategy strategy) {
        this.strategy = strategy;
    }

    public void execute(double amount) {
        strategy.pay(amount);
    }
}

// 简单工厂:根据类型获取对应策略
public class PaymentStrategyFactory {
    public static PaymentStrategy getStrategy(String type) {
        return switch (type.toLowerCase()) {
            case "wechat" -> new WeChatPay();
            case "alipay" -> new AliPay();
            case "bankcard" -> new BankCardPay();
            default -> throw new IllegalArgumentException("不支持的请款方式: " + type);
        };
    }
}

// 示例调用
public class Main {
    public static void main(String[] args) {
        String type = "alipay"; // 实际项目中可从配置、数据库、用户输入中获取
        double amount = 200.0;
        //先用工厂类根据标志位获取策略类
        PaymentStrategy strategy = PaymentStrategyFactory.getStrategy(type);
       //构建策略上下文
        PaymentContext context = new PaymentContext(strategy);
        //上下文执行具体策略
        context.execute(amount);
    }
}

注解 + 反射 + Spring Bean

如果用的是 Spring,可以把每种策略注册为一个 Bean,甚至用注解 + Map 注册策略名称,做到零 if 零 switch。

✨ 总结一图流:付款方式扩展设计模式选型对比

设计模式 是否推荐 适用说明
✅ 策略模式 ✅ 强烈推荐 多种请款方式具有共同接口但实现不同,适合抽象封装,每种方式一个类
✅ 策略 + 工厂 ✅ 实用搭配 使用工厂负责选择策略,业务类只依赖接口;便于扩展、维护清晰
⛔ if / else ❌ 垃圾桶见 新增支付方式需修改业务逻辑,违反开闭原则,代码膨胀易错
⚠️ 状态模式 ⚠️ 不太适用 更适合用于订单、流程等状态转移场景,不适合静态行为分发
⚠️ 命令模式 ⚠️ 特定场合 如果你需要封装支付命令、撤销操作、记录日志等,可以考虑命令模式
❌ 责任链模式 ❌ 不适合 更适合事件拦截、审批流等需要链式处理的场景,不适合并列选择类操作

🧠 类比理解:策略模式就像点外卖时选择不同支付方式,每个选项都是“支付”行为,但具体逻辑不同。


📌 推荐组合:

策略模式 + 简单工厂模式 + 枚举/配置管理策略类型
优雅、清晰、符合开闭原则,未来新增请款方式无需动原有业务逻辑,只需加一个新类即可。

posted @ 2025-05-08 11:07  秋夜雨巷  阅读(52)  评论(0)    收藏  举报