设计模式-策略模式

注:设计模式系列是我对《Head First设计模式》的读后感,有条件还是建议买一本,看起来很厚,但是寓教于乐的引导式学习真是让人欲罢不能,而且你也可以把它当作一本工具书。

设计模式是很多前辈通过“血淋淋”的教训总结出来的一些设计方法,它能提高程序的健壮性和可扩展性,是一种优秀的设计思想,把它们印入脑海,在以后的开发中 就可以“条件发射”的使用。当然,如果你写个"Hello Word"也要生搬硬套一种设计模式,那我就只能呵呵了。

策略模式的概念

策略模式定义了算法族,分别封装起来,让它们之间可以相互替换。策略模式让算法的变化独立于使用算法的用户。

策略模式的类图

以《Head First设计模式》中的类图为例:


用代码去理解

这是上面类图的简略版,我去掉了QuakBehavior.java接口和它的实现类。


步骤如下:

  1. 新建飞行行为接口FlyBehavior.java并实现接口;
  2. 新建Duck抽象类,并定义如类图中的方法。
    1. 其中display()是每一个Duck继承类都具有的方法,所以该方法定义成abstract类型;
    2. 飞行行为类FlyBehavior作为Duck的一个属性,便于动态的更改飞行行为.
  3. 继承Duck抽象类;
直接看代码:

  • 新建FlyBehavior.java,并提供fly方法供实现类去实现

public interface FlyBehavior {
       public void fly();
}

  • 实现该接口

//FlyWithWings.java为可以飞的鸭子
public class FlyWithWings implements FlyBehavior {
       @Override
       public void fly() {
              System.out.println("I can fly...");
       }
}
//FlyNoWay.java为不会飞的鸭子
public class FlyNoWay implements FlyBehavior {
       @Override
       public void fly() {
              System.out.println("I can not fly...");
       }
}

  • 新建Duck.java并定义相应的属性和方法
public abstract class Duck {
       public Duck() {}
       public FlyBehavior flyBehavior;
       public abstract void display();

       public void swim(){}
       public void performFly()
       {
              flyBehavior.fly();
       }

       public void setFlyBehavior(FlyBehavior flyBehavior) {
              this.flyBehavior = flyBehavior;
       }
}
  • 继承Duck

//野鸭会飞
public class MallardDuck extends Duck {

       public MallardDuck ()
       {
              flyBehavior = new FlyWithWings();
       }

       @Override
       public void display() {
              System.out.println("I'm Mallar Duck, I can fly...");
       }
}
//红头鸭也会飞
public class RedHeadDuck extends Duck {

       public RedHeadDuck () {
              flyBehavior = new FlyWithWings();
       }

       @Override
       public void display() {
              System.out.println("I'm Red Head Duck, I can fly...");
       }
}
//模型鸭不会飞
public class RubberDuck extends Duck {

       public RubberDuck () {
              flyBehavior = new FlyNoWay();
       }

       @Override
       public void display() {
              System.out.println("I'm Rubber Duck, I can not fly...");
       }
}
//诱饵鸭不会飞
public class DecoyDuck extends Duck {

       public DecoyDuck(){
              flyBehavior = new FlyNoWay();
       }

       @Override
       public void display() {
              System.out.println("I'm Decoy Duck, I can not fly...");
       }

}

  • 测试

//测试发现野鸭和红头鸭确实会飞,模型鸭和诱饵鸭确实不会飞
public class DuckTest {

       @Test
       public void testMallardDuck() {
              Duck duck = new MallardDuck();
              duck.performFly();
              duck.display();
       }

       @Test
       public void testRedHeadDuck() {
              Duck duck = new RedHeadDuck();
              duck.performFly();
              duck.display();
       }

       @Test
       public void testRubberDuck() {
              Duck duck = new RubberDuck();
              duck.performFly();
              duck.display();
       }

       @Test
       public void testDecoyDuck() {
              Duck duck = new DecoyDuck();
              duck.performFly();
              duck.display();
       }

}

  • 调用Set方法改变诱饵鸭的飞行行为
public class DuckTest {

       @Test
       public void testDecoyDuck() {
              Duck duck = new DecoyDuck();
              duck.display();
              duck.performFly();
              duck.setFlyBehavior(new FlyWithWings());
              duck.performFly();
       }

}
输出:
I'm Decoy Duck, I can not fly...
I can not fly...
I can fly...

好了,这就是策略模式,它可以定义很多算法族(我喜欢叫它行为类),我们只需要去实现这些行为就能做到较好的可扩展性,同时也体现了Java的面向接口编程。但是他的缺点也比较明显,它会有很多的行为类,我们在使用策略模式的时候必须知道这些行为类中有哪些方法,以便能选择正确的方法。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值