设计模式之策略模式

文章目录


一、策略模式的定义

策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,将每个算法封装起来,使它们可以互相替换。策略模式让算法的变化独立于使用算法的客户端,从而实现算法的灵活切换。

正如所述:"策略模式是指有一定行动内容的相对稳定的策略名称。"在软件开发中,它通过"将算法的实现与算法的使用分离",使算法可以独立于使用它的客户端而变化。


二、策略模式的核心组成

策略模式包含三个核心角色:

  1. 抽象策略角色(Strategy)

    • 由一个接口或者抽象类实现
    • 定义所有支持的算法的公共接口
  2. 具体策略角色(ConcreteStrategy)

    • 包装了相关的算法和行为
    • 实现抽象策略接口,提供具体的算法实现
  3. 环境角色(Context)

    • 持有一个策略类的引用
    • 负责与客户端交互,将具体的算法执行委托给策略对象

三、策略模式的工作原理

策略模式的核心思想是将算法的定义与使用分离,通过面向接口编程,使客户端可以在运行时根据需要选择不同的算法。

具体工作流程:

  1. 定义抽象策略接口,声明所有具体策略都需要实现的方法
  2. 实现多个具体策略类,每个类对应一种具体的算法
  3. 环境类中维护一个抽象策略的引用,提供方法用于设置具体策略
  4. 客户端创建具体策略对象,通过环境类的方法设置策略
  5. 环境类在需要时调用策略对象的方法,执行具体算法

四、策略模式的优点

  1. 避免使用多重条件语句:用多态替代if-else或switch-case,使代码更清晰
  2. 遵循开闭原则:新增策略只需实现接口,无需修改原有代码
  3. 提高代码复用性:每个策略都是独立的类,便于复用和测试
  4. 动态切换算法:可以在运行时根据需要切换不同的策略
  5. 算法的独立性:算法可以独立于客户端变化而变化,提供算法的可扩展性

五、策略模式的缺点

  1. 客户端必须知道所有策略:客户端需要知道所有的策略,并且自行决定使用哪一个策略
  2. 增加对象数量:每一个具体策略都是一个类,会增加类的数量
  3. 策略类增多:如果策略种类太多,会导致类数量过多,增加维护难度

六、策略模式的应用场景

  1. 需要使用多个变体的算法:系统需要在运行时动态地选择算法的场景
  2. 算法的使用频繁变化:需要频繁更改或扩展算法的场景
  3. 消除条件语句:需要用策略模式来替代复杂的条件分支语句的场景
  4. 多类只区别在表现行为不同:多个类只区别在表现行为不同,可以使用Strategy模式

七、策略模式的典型应用场景

  1. 支付方式选择:支付宝、微信、银联等不同支付策略
  2. 排序算法:冒泡排序、快速排序、归并排序等可互换
  3. 导航算法:步行导航、驾车导航、公共交通导航等
  4. 折扣计算:普通折扣、会员折扣、满减折扣等
  5. 邮件发送策略:SMTP、IMAP、POP3等不同邮件发送方式

八、策略模式的Java实现示例

java 复制代码
// 1. 抽象策略接口:定义计算操作
interface CalculationStrategy {
    int execute(int a, int b);
}

// 2. 具体策略:加法
class AdditionStrategy implements CalculationStrategy {
    @Override
    public int execute(int a, int b) {
        return a + b;
    }
}

// 3. 具体策略:减法
class SubtractionStrategy implements CalculationStrategy {
    @Override
    public int execute(int a, int b) {
        return a - b;
    }
}

// 4. 具体策略:乘法
class MultiplicationStrategy implements CalculationStrategy {
    @Override
    public int execute(int a, int b) {
        return a * b;
    }
}

// 5. 环境类:计算器
class Calculator {
    private CalculationStrategy strategy;
    
    public void setStrategy(CalculationStrategy strategy) {
        this.strategy = strategy;
    }
    
    public int calculate(int a, int b) {
        if (strategy == null) {
            throw new IllegalStateException("策略未设置");
        }
        return strategy.execute(a, b);
    }
}

// 6. 客户端使用
public class StrategyPatternDemo {
    public static void main(String[] args) {
        Calculator calculator = new Calculator();
        
        // 使用加法策略
        calculator.setStrategy(new AdditionStrategy());
        System.out.println("10 + 5 = " + calculator.calculate(10, 5));
        
        // 使用减法策略
        calculator.setStrategy(new SubtractionStrategy());
        System.out.println("10 - 5 = " + calculator.calculate(10, 5));
        
        // 使用乘法策略
        calculator.setStrategy(new MultiplicationStrategy());
        System.out.println("10 * 5 = " + calculator.calculate(10, 5));
    }
}

九、策略模式的优化:策略工厂

当策略类较多时,可以使用策略工厂来简化客户端的使用:

java 复制代码
// 策略工厂类
public class StrategyFactory {
    private static final Map<String, CalculationStrategy> strategies = new HashMap<>();
    
    static {
        strategies.put("add", new AdditionStrategy());
        strategies.put("subtract", new SubtractionStrategy());
        strategies.put("multiply", new MultiplicationStrategy());
    }
    
    public static CalculationStrategy getStrategy(String type) {
        if (type == null || type.isEmpty()) {
            throw new IllegalArgumentException("type should not be empty");
        }
        return strategies.get(type);
    }
}

十、总结

  • 策略模式是软件设计中非常实用的设计模式,它通过将算法封装为独立的类,使系统更加灵活、可扩展。它解决了"多重条件语句"的代码坏味道,使代码更加清晰易读。

  • 正如所述:"策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。"通过策略模式,我们可以在不修改客户端代码的情况下,动态地选择和切换算法,使系统更加符合开闭原则。

  • 在实际开发中,策略模式是处理"算法族"问题的首选模式,尤其适用于需要在运行时动态选择算法的场景。

相关推荐
_院长大人_2 小时前
设计模式-工厂模式
java·开发语言·设计模式
王道长服务器 | 亚马逊云18 小时前
AWS + 苹果CMS:影视站建站的高效组合方案
服务器·数据库·搜索引擎·设计模式·云计算·aws
在未来等你18 小时前
AI Agent设计模式 Day 1:ReAct模式:推理与行动的完美结合
设计模式·llm·react·ai agent·plan-and-execute
乐悠小码1 天前
Java设计模式精讲---03建造者模式
java·设计模式·建造者模式
_院长大人_1 天前
设计模式-代理模式
设计模式·代理模式
guangzan1 天前
TypeScript 中的单例模式
设计模式
乐悠小码2 天前
Java设计模式精讲---02抽象工厂模式
java·设计模式·抽象工厂模式
乙己4073 天前
设计模式——原型模式(prototype)
设计模式·原型模式
⑩-3 天前
浅学Java-设计模式
java·开发语言·设计模式