Fork me on GitHub

策略模式和工厂模式中新增一个行为

前置:策略+工厂重构if

https://www.cnblogs.com/aeolian/p/18865859

🧠 策略类新增行为

在使用策略模式(配合工厂)管理“请款方式”时,若要为已有策略添加新的行为(比如 refund() 退款、queryStatus() 状态查询),可能面临接口设计和扩展性问题。

“添加一个行为”,不是“添加一个策略实现”。
• 已有策略类(比如 AliPay, WeChatPay);
• 想在这些类中统一增加一个新的方法,比如 refund()(退款)或者 queryStatus()(查询支付状态);
• 而不是新增一种支付方式。

✅ 方式一:直接在接口中新增方法

适合所有策略类都要实现这个新行为的情况。

public interface PaymentStrategy {
    void pay(double amount);
    void refund(double amount); // 新增方法
}

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

    public void refund(double amount) {
        // 退款逻辑
    }
}

📌 优点:
• 明确、统一,调用方便;
• 类型安全,代码清晰。

⚠️ 缺点:
• 所有实现类都必须改;
• 如果某些类不支持该行为,只能抛异常或空实现,违背接口隔离原则。

✅ 方式二:接口分离 + 组合判断

若不是所有支付方式都支持新行为,可以将其拆成独立接口。

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

public class AliPay implements PaymentStrategy, Refundable {
    public void pay(double amount) {
        // ...
    }

    public void refund(double amount) {
        // ...
    }
}

调用端按需判断:

PaymentStrategy strategy = getStrategy();
if (strategy instanceof Refundable r) {
    r.refund(100.0);
}

📌 优点:
• 遵循接口隔离原则;
• 不影响现有实现类;
• 拓展更灵活。

✅ 方式三:装饰器模式添加行为(不动原类)

如果不希望修改原有类结构,可用装饰器包裹原策略,添加额外行为。

public class RefundableWrapper implements PaymentStrategy {
    private final PaymentStrategy delegate;

    public RefundableWrapper(PaymentStrategy delegate) {
        this.delegate = delegate;
    }

    @Override
    public void pay(double amount) {
        delegate.pay(amount);
    }

    public void refund(double amount) {
        // 添加新行为,如退款、日志等
    }
}

📌 优点:
• 不动原代码;
• 可动态叠加行为(如日志、监控、缓存);
• 拓展性强,适合 AOP 风格开发。

🧠 总结对比表:策略模式中添加新行为的三种方式

使用场景 推荐方式 优点 缺点
所有策略类都必须支持该新行为 ✅ 在接口中直接添加方法 明确统一、类型安全、调用方便 所有实现类都要改,可能违背接口隔离原则
只有部分策略类需要支持该新行为 ✅ 拆分为单独接口 + 组合判断 拓展灵活,符合接口隔离原则,不影响其他类 需要额外进行类型判断(instanceof
不希望动现有策略类,动态增强行为 ✅ 使用装饰器模式(Wrapper) 不动原代码、易于扩展、适合叠加日志/缓存/验证等功能 包装逻辑相对复杂、理解成本略高

🎯 小贴士:

  • 如果你是在维护一个稳定系统,建议优先使用“组合 + 装饰器”方式;
  • 如果你在重构或设计新系统,尽量遵循“接口分离”原则,提前预留行为扩展口;
  • 不要害怕拆接口,也不要为了“统一”而强求所有类都支持不相关的行为。

✨ 提醒:策略模式的初衷是封装行为的变化,而不是一次性定死行为列表。当行为本身也在扩展,不要只想着“继承”,要用组合、拆分、装饰等方式以变应变。

posted @ 2025-05-13 11:25  秋夜雨巷  阅读(15)  评论(0)    收藏  举报