设计模式 - 策略设计模式
策略设计模式(Strategy Pattern)是一种行为设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以互相替换。这种模式让算法独立于使用它的客户端。简而言之,策略模式允许在运行时更改算法的行为。
策略模式的组成部分:
- Context(上下文):
- 上下文指的是客户端程序,它使用某种策略。上下文通常包含对一个策略对象的引用。
- Strategy(策略接口)
- 这是一个接口或抽象类,定义了所有支持的算法的公共接口。这是策略类必须要实现的接口。
- 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
策略模式的优点:
-
灵活性高:策略模式允许在运行时动态地选择算法。这意味着可以根据不同的条件选择不同的行为,增强了系统的灵活性。
-
易于扩展:新增一个算法非常容易,只需要新增一个具体策略类即可,而不需要修改已有的代码。这符合开闭原则(Open/Closed Principle),即对扩展开放,对修改关闭。
-
减少选择条件语句:使用策略模式可以消除条件选择语句,如 if...else 或者 switch...case,从而使代码更清晰、更易于理解。
-
更好的封装:每个算法都被封装在一个策略类中,算法的实现细节对客户端来说是透明的。这样可以防止客户端直接修改算法的实现。
-
解耦:策略模式将算法的使用从算法的实现中分离出来,降低了上下文与具体算法之间的耦合度。
策略模式的优点:
- 类的数量增加:每一个新的算法都需要一个新的具体策略类,这会导致类的数量增加,从而增加了系统的设计和维护成本。
- 客户端必须要了解策略:客户端必须知道所有的策略类,并自行决定使用哪一个。如果客户端不知道如何选择合适的策略,那么策略模式的优势就会减弱。
- 存在过度设计的风险:在一些简单的情况下,使用策略模式可能会被认为是过度设计,特别是当只有少数几种算法并且不太可能扩展时。
- 对象创建开销:在某些情况下,如果策略对象的创建成本较高,频繁地创建和销毁策略对象可能会成为一个性能问题。