策略模式 Strategy Pattern
策略模式定义了算法簇,分别封装起来,让他们之间可以互相替换,此模式然该算法的变化独立于使用算法的客户。
我的初步理解是:感觉像插件,把算法做成插件,要什么功能就插入什么算法,给把青龙偃月刀就是关云长,给把青钢剑就是赵云,给把丈八蛇矛就是张飞了。
该模式与面向对象的多态对比,优点在于后期修改的灵活性,不会有继承导致的子类冗余(某个子类不需要父类中的一些方法),以及可以动态添加新属性。
下面是示例代码(使用书中示例,讲解如何定义各种鸭子,嗯,会飞会叫的鸭子):
一、定义鸭子的各种行为(定义算法簇),一个“飞”行为和一个“叫”行为,分别定义一个接口。
1,“飞”和“叫”接口
飞:
package behavior; public interface FlyBehavior { public void fly(); }
叫:
package behavior; public interface QuackBehavior { public void quack(); }
2,接口的具体实现:
用翅膀飞:
package behavior; public class FlyWithWings implements FlyBehavior { @Override public void fly() { // TODO Auto-generated method stub System.out.println("我用翅膀飞!"); } }
不会飞:
package behavior; public class FlyNoWay implements FlyBehavior { @Override public void fly() { // TODO Auto-generated method stub System.out.println("我不会飞,就这样!"); } }
呱呱叫:
package behavior; public class QuackWithGG implements QuackBehavior { @Override public void quack() { // TODO Auto-generated method stub System.out.println("呱呱叫!"); } }
吱吱叫:
package behavior; public class QuackWithZZ implements QuackBehavior { @Override public void quack() { // TODO Auto-generated method stub System.out.println("吱吱叫!"); } }
二、定义和构造具体的鸭子
1、定义鸭子的父类:
package model; import behavior.FlyBehavior; import behavior.QuackBehavior; public abstract class Duck { private FlyBehavior flyBehavior; private QuackBehavior quackBehavior; public FlyBehavior getFlyBehavior() { return flyBehavior; } public void setFlyBehavior(FlyBehavior flyBehavior) { this.flyBehavior = flyBehavior; } public QuackBehavior getQuackBehavior() { return quackBehavior; } public void setQuackBehavior(QuackBehavior quackBehavior) { this.quackBehavior = quackBehavior; } public void perfomFly() { flyBehavior.fly(); } public void perfomQuack() { quackBehavior.quack(); } }
2、具体构造一个鸭子:
package model; import behavior.FlyBehavior; import behavior.FlyNoWay; import behavior.FlyWithWings; import behavior.QuackBehavior; import behavior.QuackWithGG; import behavior.QuackWithZZ; public class DownNoDuck extends Duck { public DownNoDuck(FlyBehavior fly, QuackBehavior quack) { setFlyBehavior(fly); setQuackBehavior(quack); } /** * @param args */ public static void main(String[] args) { Duck duck1 = new DownNoDuck(new FlyNoWay(), new QuackWithZZ()); Duck duck2 = new DownNoDuck(new FlyWithWings(), new QuackWithGG()); duck1.perfomFly(); duck1.perfomQuack(); duck2.perfomFly(); duck2.perfomQuack(); } }
总结:从代码中看出,这里将行为接口定义成了Duck的属性,然后使用具体的行为去构造具体的Duck,这样,就得到了我们想要的Duck。而且我们还可以在构造玩Duck后动态地改变Duck的属性,这就是灵活性。
上面示例代码将打印:
我不会飞,就这样! 吱吱叫! 我用翅膀飞! 呱呱叫!