策略模式

定义一系列算法,封装每个算法,并使它们可以互换。
策略模式(Strategy Pattern)可以让算法独立于使用它的客户端。

Class Diagram

  • Strategy 接口定义了一个算法族,它们都实现了 behavior() 方法
  • ontext 是使用到该算法族的类,其中的 doSomething() 方法会调用 behavior(),setStrategy(Strategy) 方法可以动态地改变 strategy 对象,也就是说能动态地改变 Context 所使用的算法
  • 策略模式的策略类可以作为单例,如果设置为成员变量时可以不设置单例。
  • 与状态模式的比较

状态模式的类图和策略模式类似,并且都是能够动态改变对象的行为。但是状态模式是通过状态转移来改变 Context 所组合的 State 对象,而策略模式是通过 Context 本身的决策来改变组合的 Strategy 对象。所谓的状态转移,是指 Context 在运行过程中由于一些条件发生改变而使得 State 对象发生改变,注意必须要是在运行过程中。

状态模式主要是用来解决状态转移的问题,当状态发生转移了,那么 Context 对象就会改变它的行为;而策略模式主要是用来封装一组可以互相替代的算法族,并且可以根据需要动态地去替换 Context 使用的算法。

Implementation

策略接口

1
2
3
4
public abstract class Strategy {
// 算法方法
public abstract void behavior();
}

具体策略

1
2
3
4
5
6
7
8
9
10
11
12
13
public class ConcreteStrategyA extends Strategy {
@Override
public void behavior() {
System.out.println("策略A");
}
}

public class ConcreteStrategyB extends Strategy {
@Override
public void behavior() {
System.out.println("策略B");
}
}

策略使用者

1
2
3
4
5
6
7
8
9
10
11
public class Context {
Strategy strategy;

public Context(Strategy strategy) {
this.strategy = strategy;
}

public void doSomething(){
strategy.behavior();
}
}

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
public class StrategyTest {


@Test
public void test() throws Exception{
Context a = new Context(new ConcreteStrategyA());
a.doSomething();

Context b = new Context(new ConcreteStrategyB());
b.doSomething();
}

}

Example

  • javax.servlet.Filter#doFilter()
  • java.util.Comparator#compare()

Usage

  • 比如在类的构造器中,设置handler,方法内 handler.handle();

Refence