策略模式
策略模式定义一系列算法,分别封装起来,让他们之间可以相互转换,策略模式可以让算法的变化独立于使用算法的客户。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| public abstract class Duck { private FlyBehavior flyBehavior; private QuackBehavior quackBehavior; public Duck() { this.flyBehavior=new FlyBehaviorDefualtImpl(); this.quackBehavior=new QuackBehaviorDefaultImpl(); } public void performFly(){ this.flyBehavior.fly(); } public void performQuack(){ this.quackBehavior.quack(); } public void swim(){ log.info("All ducks float, event decoys"); } abstract void display(); public void setFlyBehavior(FlyBehavior flyBehavior) { this.flyBehavior = flyBehavior; } public void setQuackBehavior(QuackBehavior quackBehavior) { this.quackBehavior = quackBehavior; } }
|
定义了一个抽象的鸭子基类,它有最基本的四个方法,执行飞的行为方法performFly()
,执行叫的行为方法performQuack()
,还有游泳和显示方法。
不同的鸭子子类显示行为不同,所以这里设置成abstract的。所有的鸭子都可以游泳。这里直接定义好一个具体的方法swim
,但是鸭子的飞和叫方法,不同的
子类是不同、,虽然这里也可以将这两个方法设计成抽象的方法,由具体的子类去实现,但是当鸭子的子类非常多的时候,各自都需要重新实现飞和叫的方法。这里
为了复用而使用继承,并不完美。因为你很难知道以后这个抽象基类会新增什么其他的抽象方法,那样所有的具体子类都需要实现这个抽象方法。运行时的行为也不容易改变,
这里可以使用策略模式将变化的部分单独封装起来,好让其他部分不受影响,这里有一个设计原则
找出应用中可能需要变化的地方,把他们独立出来,不要和那些不需要变化的代码混在一起。
可以将鸭子的行为单独的放在分开的类中,此类专门提供某行为接口实现,这样鸭子类就不再需要知道行为的实现细节。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public interface FlyBehavior { void fly(); } public class FlyBehaviorDefualtImpl implements FlyBehavior { @Override public void fly() { log.info("I'am flying !"); } } public class FlyNoWayBehaviorImpl implements FlyBehavior { @Override public void fly() { log.info("I canot fly!"); } }
|
这样设计的好处是可以动态的改变鸭子的行为,只需要set不同的behavior实现就行了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public static void main(String[] args) { Duck duck=new MallardDuck(); log.info("默认行为>>>>>>>."); duck.display(); duck.performFly(); duck.performQuack(); log.info("动态改变行为>>>>>>>."); duck.setFlyBehavior(new FlyNoWayBehaviorImpl()); duck.setQuackBehavior(new MuteQuackBehaviorImpl()); duck.display(); duck.performFly(); duck.performQuack(); }
|