掌握设计模式--策略模式

策略模式(Strategy Pattern)

策略模式是一种行为设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,从而让算法的变化独立于使用它们的客户端代码。

策略模式的核心在于为算法的实现提供统一的接口,并通过动态选择具体实现来实现灵活性。

组成部分

  1. Context(上下文类):

    持有对某个策略对象的引用,并定义客户端需要的接口,负责在运行时动态切换策略。

  2. Strategy(策略接口):

    定义所有支持的算法的公共接口。

  3. ConcreteStrategy(具体策略实现):

    实现 Strategy 接口的具体算法。

代码示例

以下是使用策略模式实现不同的支付方式的动态切换。信用卡支付和微信支付的动态切换。

类图

策略接口

java 复制代码
// 策略接口
public interface PaymentStrategy {
    void pay(int amount);
}

具体策略实现

java 复制代码
// 具体策略实现 - 信用卡支付
public class CreditCardPayment implements PaymentStrategy {
    private String cardNumber;

    public CreditCardPayment(String cardNumber) {
        this.cardNumber = cardNumber;
    }

    @Override
    public void pay(int amount) {
        System.out.println("交易金额 " + amount + " 使用的卡号: " + cardNumber);
    }
}
// 具体策略实现 - 微信支付
public class WxPayment implements PaymentStrategy {
    private String phoneNumber;

    public WxPayment(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    @Override
    public void pay(int amount) {
        System.out.println("交易金额 " + amount + " 使用的手机号: " + phoneNumber);
    }
}

上下文

java 复制代码
// 上下文类
public class PaymentContext {
    private PaymentStrategy strategy;

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

    public void setStrategy(PaymentStrategy strategy) {
        this.strategy = strategy;
    }

    public void executePayment(int amount) {
        strategy.pay(amount);
    }
}

测试代码

java 复制代码
public class StrategyPatternDemo {
    public static void main(String[] args) {
        // 使用信用卡支付
        PaymentContext context = new PaymentContext(new CreditCardPayment("1234-5678-9012-3456"));
        context.executePayment(100);

        // 切换到Wx支付
        context.setStrategy(new WxPayment("13112345678"));
        context.executePayment(200);
    }
}

测试结果

交易金额 100 使用的卡号: 1234-5678-9012-3456

交易金额 200 使用的手机号: 13112345678

优缺点和适用场景

优点

  1. 开放-封闭原则: 新的策略可以在不修改现有代码的情况下添加。

  2. 提高代码灵活性: 可以动态地在运行时选择算法。

  3. 消除冗长的条件分支: 使用策略模式代替 if-elseswitch-case 条件判断。

缺点

  1. 类的数量增加: 每个策略需要定义一个类,可能导致类数量增多。

  2. 客户端需要知道所有策略: 客户端必须了解策略的作用并选择合适的策略。

适用场景

  1. 多个算法只有在行为上稍有不同的情况下。
  2. 需要动态选择算法或者行为的情况下。
  3. 避免使用条件语句(if-elseswitch-case)来管理算法时。

实际应用

  1. 数据加密算法选择(AES、RSA等)
  2. 数据压缩算法(ZIP、GZIP)
  3. 不同类型的文件解析(JSON、XML、YAML)

策略模式与其他模式的对比

  1. 状态模式: 状态模式的行为是状态驱动的,而策略模式的行为是由客户端选择驱动的。

  2. 工厂模式: 工厂模式用于创建对象,而策略模式关注的是行为的动态切换。

  3. 桥接模式: 桥接模式侧重于分离抽象和实现及多维度的扩展;而策略模式用于封装算法或行为,单维度的扩展。

  4. 装饰模式: 使用一系列装饰器类,通过组合的方式增强对象的功能。装饰器的核心在于"增强"。

  5. 策略模式: 客户端在运行时选择合适的策略来完成特定任务。策略模式的核心在于"替换"。

总结

策略设计模式定义了一系列算法(策略),将每个算法封装到独立的策略类中,并通过上下文类动态地选择和使用不同的策略,从而让算法的变化独立于使用算法的客户端。

需要查看往期设计模式文章的,可以在个人主页中或者文章开头的集合中查看,可关注我,持续更新中。。。


超实用的SpringAOP实战之日志记录

2023年下半年软考考试重磅消息

通过软考后却领取不到实体证书?

计算机算法设计与分析(第5版)

Java全栈学习路线、学习资源和面试题一条龙

软考证书=职称证书?

软考中级--软件设计师毫无保留的备考分享

相关推荐
杨充19 小时前
10.可测试性实战设计
设计模式·开源·代码规范
杨充19 小时前
9.重构十二式的实战
设计模式·开源·代码规范
杨充19 小时前
6.设计原则的全景图
设计模式·开源·全栈
杨充19 小时前
2.面向对象的特性
设计模式
杨充19 小时前
7.SOLID原则案例汇
设计模式·开源·全栈
杨充19 小时前
8.反模式与坏味道
设计模式·开源·代码规范
杨充19 小时前
3.接口vs抽象类比较
设计模式
咖啡八杯1 天前
文法、BNF与AST
java·设计模式·解释器模式·ast·文法
咖啡八杯1 天前
GoF设计模式——解释器模式
java·后端·spring·设计模式