策略设计模式

Lily Flower / 2025-02-18 / 原文

设计模式 - 策略设计模式

策略设计模式(Strategy Pattern)是一种行为设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以互相替换。这种模式让算法独立于使用它的客户端。简而言之,策略模式允许在运行时更改算法的行为。

策略模式的组成部分:

  1. Context(上下文):
    • 上下文指的是客户端程序,它使用某种策略。上下文通常包含对一个策略对象的引用。
  2. Strategy(策略接口)
    • 这是一个接口或抽象类,定义了所有支持的算法的公共接口。这是策略类必须要实现的接口。
  3. Concrete Strategies(具体策略):
    • 具体策略实现了策略接口,并提供了具体的算法实现。

策略模式的工作原理

在策略模式中,策略上下文将请求对象委托给一个具体的策略对象,而这个策略对象是在运行时动态选择的,上下文并不知道具体使用的是哪一个具体策略,因此可以灵活的切换算法,而不需要修改上下文以及客户端的代码。

使用场景

  • 多种算法互换:当存在多种算法时,但是这些算法相互之间没有依赖关系时,可以使用策略模式。
  • 算法的频繁更改:当算法需要频繁更改时,使用策略模式可以避免代码重复。
  • 非侵入性扩展:当希望在不修改原有代码的基础上扩展新功能时,策略模式可以实现这种扩展。
  • 条件语句的消除:如果发现代码中有很多类似“if...else”或“switch...case”的条件选择语句,那么可以考虑使用策略模式来将算法抽象化。

示例代码

下面举一个简单的示例来演示一下策略设计模式

// 策略设计模式
public class StrategyPattern {
    public static void main(String[] args) {
        CalculateContext context = new CalculateContext(new AddOperation());
        System.out.println(context.calculate(12, 24));

        context = new CalculateContext(new SubOperation());
        System.out.println(context.calculate(12, 24));
    }
}

// 策略接口(计算策略接口)
interface CalculateStrategy {
    int doOperation(int a, int b);
}

// 策略上下文
class CalculateContext {
    private CalculateStrategy calculateStrategy;

    public CalculateContext(CalculateStrategy calculateStrategy) {
        this.calculateStrategy = calculateStrategy;
    }

    // 执行策略中的方法
    public int calculate(int a, int b) {
        return calculateStrategy.doOperation(a, b);
    }
}

// 具体的策略实现类(加法)
class AddOperation implements CalculateStrategy {

    @Override
    public int doOperation(int a, int b) {
        return a + b;
    }
}

// 具体的策略实现类(减法)
class SubOperation implements CalculateStrategy{

    @Override
    public int doOperation(int a, int b) {
        return a - b;
    }
}

运行结果如下:

36
-12

策略模式的优点:

  1. 灵活性高:策略模式允许在运行时动态地选择算法。这意味着可以根据不同的条件选择不同的行为,增强了系统的灵活性。

  2. 易于扩展:新增一个算法非常容易,只需要新增一个具体策略类即可,而不需要修改已有的代码。这符合开闭原则(Open/Closed Principle),即对扩展开放,对修改关闭。

  3. 减少选择条件语句:使用策略模式可以消除条件选择语句,如 if...else 或者 switch...case,从而使代码更清晰、更易于理解。

  4. 更好的封装:每个算法都被封装在一个策略类中,算法的实现细节对客户端来说是透明的。这样可以防止客户端直接修改算法的实现。

  5. 解耦:策略模式将算法的使用从算法的实现中分离出来,降低了上下文与具体算法之间的耦合度。

策略模式的优点:

  1. 类的数量增加:每一个新的算法都需要一个新的具体策略类,这会导致类的数量增加,从而增加了系统的设计和维护成本。
  2. 客户端必须要了解策略:客户端必须知道所有的策略类,并自行决定使用哪一个。如果客户端不知道如何选择合适的策略,那么策略模式的优势就会减弱。
  3. 存在过度设计的风险:在一些简单的情况下,使用策略模式可能会被认为是过度设计,特别是当只有少数几种算法并且不太可能扩展时。
  4. 对象创建开销:在某些情况下,如果策略对象的创建成本较高,频繁地创建和销毁策略对象可能会成为一个性能问题。