设计模式也是在工作中才会发现其作用。在规模较小的情况下,往往随意写来比较方便快速,可是对于大型的系统来说,各个部分用上合适的设计模式可以更好的维护系统,也更加的清晰。最近看了看一些web框架的源码,比如用的最多的Spring,一个web请求就会经过很多层的处理,其中用了很多设计模式,如果不了解则很难理解为什么要如此设计。所以还是从基础的开始吧。
下面说的是一个比较简单的 策略模式。
策略模式的定义:一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
不像其他模式的定义显得很绕,策略模式的含义一看就比较清晰了。行为或者算法在运行时可以更改,首先能想到的便是通过面向对象中的多态来达到目的。在运行的过程中,根据需要动态的设定对象,对于调用者来说只要持有他们共同的接口就行了。正好,策略模式也正是这样。
看下面的例子(来自《Head First 设计模式》):
对于一只鸭子,它有飞和叫的行为,但是不同的鸭子表现出来的不一样。如果在一个类中表示所有的鸭子,则要进行各种判断,所以使用策略模式,将能够根据需要表现出不同鸭子的性质。
首先定义它的飞的行为:
1 2 3 4 5
   | package io.lovs.learn.design.strategy;
  public interface FlyBehavior {     void fly(); }
   | 
 
再定义叫的行为:
1 2 3 4 5
   | package io.lovs.learn.design.strategy;
  public interface QuackBehavior {     void quack(); }
   | 
 
对两种行为添加不同的实现,首先是飞的行为:
1 2 3 4 5 6 7 8
   | package io.lovs.learn.design.strategy;
  public class FlyWithWings implements FlyBehavior {     @Override     public void fly() {         System.out.println("start fly");     } }
   | 
 
1 2 3 4 5 6 7 8
   | package io.lovs.learn.design.strategy;
  public class FlyNoWay implements FlyBehavior {     @Override     public void fly() {         System.out.println("I can't fly");     } }
   | 
 
上面分别定义了一个飞和不回飞的行为
然后是叫的行为:
1 2 3 4 5 6 7 8
   | package io.lovs.learn.design.strategy;
  public class Squeak implements QuackBehavior {     @Override     public void quack() {         System.out.println("Squeak");     } }
   | 
 
1 2 3 4 5 6 7 8
   | package io.lovs.learn.design.strategy;
  public class MuteQuack implements QuackBehavior {     @Override     public void quack() {         System.out.println("silence");     } }
   | 
 
这里定义了叫和不叫的行为
然后定义一只抽象的鸭子,它将包含鸭子的基本属性,具体的鸭子可继承它然后实现各自的特点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
   | package io.lovs.learn.design.strategy;
  public abstract class Duck {
      FlyBehavior flyBehavior;     QuackBehavior quackBehavior;
      public void display() {         System.out.println("It's a duck");     }
      abstract void fly();     abstract void quack();
      public void setFlyBehavior(FlyBehavior flyBehavior) {         this.flyBehavior = flyBehavior;     }
      public void setQuackBehavior(QuackBehavior quackBehavior) {         this.quackBehavior = quackBehavior;     } }
   | 
 
再来实现一只具体的鸭子
1 2 3 4 5 6 7 8 9 10 11 12 13
   | package io.lovs.learn.design.strategy;
  public class RealDuck extends Duck {     @Override     void fly() {         flyBehavior.fly();     }
      @Override     void quack() {         quackBehavior.quack();     } }
   | 
 
具体的某只鸭子继承了基本的鸭子的属性,在这里,主要实现了各自的叫和飞的行为。从抽象鸭子的定义中可以看到,它不直接实现飞和叫的功能,而是持有了飞和叫的接口,通过设置具体的飞与叫的类来实现该动作,达到了动态改变的效果,如果需要改变其行为,只要重新设置新的属性就好了。
测试类:
1 2 3 4 5 6 7 8 9 10 11 12
   | package io.lovs.learn.design.strategy;
  public class Test {     public static void main(String[] args) {         Duck duck = new RealDuck();         duck.setFlyBehavior(new FlyNoWay());         duck.setQuackBehavior(new Quack());         duck.display();         duck.fly();         duck.quack();     } }
   | 
 
 输出:
1 2 3
   | It's a duck I can't fly quack
   | 
 
策略模式相对简单,在书中也作为第一个讲解的内容。如果自己想象平时做的东西,在某些地方已经不经意中到了这样的模式。所以模式来源于实践当中,而单独看这些模式也没有意义,要在实际项目中真正的运用才算是发挥了真正的作用。这个模式就到这里吧。