定义一系列算法,封装每个算法,并使它们可以互换。
策略模式(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