设计模式--行为型:策略模式

策略模式:定义一系列的算法,单独封装并使它们可以相互替换。这一模式可以使算法独立于使用它的客户而变化

策略模式

策略模式 Strategy[ˈstrætədʒi] Pattern:定义一系列算法的方法,从概念上看,所有的这些算法完成的多是相同的工作,只是实现不同,他们可以使用相同的方法来调用算法,减少了类之间的耦合。

类图结构

0069-Strategy-uml-classdiag.png

结构解析

  • Strategy
    抽象类,策略类,定义算法。
  • ConcreteStrategy
    实现类,算法的具体实现。
  • Context
    环境类,上下文,持有当前策略的引用。客户端可以通过上下文动态切换算法。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// 1. Strategy
public abstract class Strategy {
public abstract void algorithm();
}

// 2. ConcreteStrategy
public class ConcreteStrategy1 extends Strategy {
@Override
public void algorithm() {
System.out.println("ConcreteStrategy1: Bubble sort.");
}
}

public class ConcreteStrategy2 extends Strategy {
@Override
public void algorithm() {
System.out.println("ConcreteStrategy2: Insertion sort.");
}
}

// 3. Context
public class Context {
private Strategy strategy;

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

public void algorithm(){
strategy.algorithm();
}
}


// 4. Test
public class TestStrategy {
public static void main(String[] args) {
Strategy strategy = new ConcreteStrategy1();
Context context = new Context();
context.setStrategy(strategy);
context.algorithm();

strategy = new ConcreteStrategy2();
context.setStrategy(strategy);
context.algorithm();
}
}

// 5. Result
ConcreteStrategy1: Bubble sort.
ConcreteStrategy2: Insertion sort.

示例中,策略的选择由客户端来决定。

总结

策略模式简化了单元测试,每个算法是一个独立的类,可以通过自己的接口单独测试。策略模式同时体现了开闭原则:策略模式把一系列的可变算法进行封装,从而定义了良好的程序结构,在出现新的算法的时候,可以很容易的将新的算法实现加入到已有的系统中,而已有的实现不需要修改。

状态模式与策略模式的异同

  • 相同点
    策略模式也是为了消除或者简化条件语句,和责任链模式,状态模式很类似。所以类图结构上看起来几乎没有太大区别。
  • 不同点
    状态模式中各个状态子类都必须知道它的下一个状态是什么,并且逻辑判断都转移到子类中,客户端并不了解状态的转换逻辑。而策略模式中各个子类是并级的,可以相互替换,他们并不存在状态转换的关系。策略模式是针对单一并行算法的替换,客户端需要提前了解各算法差异,并在策略模式中指定一种算法。

策略模式和责任链模式的异同

  • 相同点
    在功能职责上都是用来简化或消除条件判断,客户端在使用时需要提前指定使用哪种策略,或者指定责任链模式中的下一个继任者。
  • 不同点
    两者在类图上有区别,责任链模式需要持有下一个责任人的引用,策略模式多一个上下文类,由上下文类来持有具体的策略。责任链模式存在级差,每个子类拥有不同的责任权限;而策略模式子类都是并级的,客户端在选用时只需要选择一种策略。

参考文档

0%