1. 意图(Intent)

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

2. 类图(Class Diagram)

cd1be8c2-755a-4a66-ad92-2e30f8f47922.png

  • Strategy 接口定义了一个算法族,它们都实现了 behavior() 方法。
  • Context 是用到该算法族的类,其中的 doSomething() 方法会调用 behavior(),setStrategy(Strategy) 方法可以动态地改变 strategy 对象,也就是说能动态地改变 Context 所使用的算法。

    3. 实现(Implementation)

I 画图案例

首先,先定义一个策略接口:[ Strategy ]

  1. public interface Strategy {
  2. public void draw(int radius, int x, int y);
  3. }

然后我们定义具体的几个策略:[ ConcreteStrategy ]

  1. public class RedPen implements Strategy {
  2. @Override
  3. public void draw(int radius, int x, int y) {
  4. System.out.println("用红色笔画图,radius:" + radius + ", x:" + x + ", y:" + y);
  5. }
  6. }
  1. public class GreenPen implements Strategy {
  2. @Override
  3. public void draw(int radius, int x, int y) {
  4. System.out.println("用绿色笔画图,radius:" + radius + ", x:" + x + ", y:" + y);
  5. }
  6. }
  1. public class BluePen implements Strategy {
  2. @Override
  3. public void draw(int radius, int x, int y) {
  4. System.out.println("用蓝色笔画图,radius:" + radius + ", x:" + x + ", y:" + y);
  5. }
  6. }

使用策略的类:[ Context ]

  1. public class Context {
  2. private Strategy strategy;
  3. public Context(Strategy strategy){
  4. this.strategy = strategy;
  5. }
  6. public int executeDraw(int radius, int x, int y){
  7. return strategy.draw(radius, x, y);
  8. }
  9. }

客户端演示:

  1. public class Client {
  2. public static void main(String[] args) {
  3. Context context = new Context(new BluePen()); // 使用绿色笔来画
  4. context.executeDraw(10, 0, 0);
  5. }
  6. }

放到一张图上,让大家看得清晰些:
strategy-1.png这个时候,大家有没有联想到结构型模式中的桥梁模式,它们其实非常相似,我把桥梁模式的图拿过来大家对比下:
bridge-1.png
要我说的话,它们非常相似,桥梁模式在左侧加了一层抽象而已。桥梁模式的耦合更低,结构更复杂一些。

II 鸭子案例

设计一个鸭子,它可以动态地改变叫声。这里的算法族是鸭子的叫声行为。

首先,先定义一个策略接口:[ Strategy ]

  1. public interface QuackBehavior {
  2. void quack();
  3. }

然后我们定义具体的几个策略:[ ConcreteStrategy ]

  1. //嘎嘎叫
  2. public class Quack implements QuackBehavior {
  3. @Override
  4. public void quack() {
  5. System.out.println("quack!");
  6. }
  7. }
  1. //吱吱叫
  2. public class Squeak implements QuackBehavior{
  3. @Override
  4. public void quack() {
  5. System.out.println("squeak!");
  6. }
  7. }

使用策略的鸭子类:[ Context ]

  1. public class Duck {
  2. private QuackBehavior quackBehavior;
  3. public void performQuack() {
  4. if (quackBehavior != null) {
  5. quackBehavior.quack();
  6. }
  7. }
  8. public void setQuackBehavior(QuackBehavior quackBehavior) {
  9. this.quackBehavior = quackBehavior;
  10. }
  11. }

客户端演示:

  1. public class Client {
  2. public static void main(String[] args) {
  3. Duck duck = new Duck();
  4. duck.setQuackBehavior(new Squeak());
  5. duck.performQuack();
  6. duck.setQuackBehavior(new Quack());
  7. duck.performQuack();
  8. }
  9. }
  10. //输出结果:
  11. //squeak! 嘎嘎叫
  12. //quack! 吱吱叫

4. JDK

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