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

策略模式(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全栈学习路线、学习资源和面试题一条龙

软考证书=职称证书?

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

相关推荐
hope_wisdom17 分钟前
实战设计模式之命令模式
设计模式·系统架构·软件工程·命令模式·架构设计
吾与谁归in18 分钟前
【C#设计模式(23)——模板方法模式(Template Method Pattern)】
设计模式·c#·模板方法模式
zhulangfly2 小时前
【Java设计模式-5】装饰模式:给咖啡加点“佐料”
java·设计模式·装饰模式
jf加菲猫2 小时前
3 生成器(Builder)模式
c++·设计模式
ZoeLandia4 小时前
从前端视角看设计模式之创建型模式篇
前端·javascript·设计模式
Camel卡蒙4 小时前
Java设计模式——单例模式(特性、各种实现、懒汉式、饿汉式、内部类实现、枚举方式、双重校验+锁)
java·单例模式·设计模式
power-辰南4 小时前
设计模式之结构型模式
设计模式
我真不会起名字啊4 小时前
“深入浅出”系列之设计模式篇:(0)什么是设计模式
设计模式
幸运小圣5 小时前
前端常见的设计模式之【单例模式】
前端·单例模式·设计模式
电子科技圈5 小时前
快速、可靠且高性价比的定制IP模式提升芯片设计公司竞争力
设计模式·软件工程·团队开发·设计规范