设计模式学习笔记之一:策略模式
策略模式定义了算法族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。
FlyBehavior
package com.singland.dp.strategy; public interface FlyBehavior { void fly(); }
FlyNoWay
package com.singland.dp.strategy; public class FlyNoWay implements FlyBehavior { @Override public void fly() { System.out.println("I cannot fly"); } }
FlyWithWing
package com.singland.dp.strategy; public class FlyWithWing implements FlyBehavior { @Override public void fly() { System.out.println("I can fly"); } }
QuackBehavior
package com.singland.dp.strategy; public interface QuackBehavior { void quack(); }
Quack
package com.singland.dp.strategy; public class Quack implements QuackBehavior { @Override public void quack() { System.out.println("quack"); } }
MuteQuack
package com.singland.dp.strategy; public class MuteQuack implements QuackBehavior { @Override public void quack() { System.out.println("No sound"); } }
Duck
package com.singland.dp.strategy; public abstract class Duck { FlyBehavior flyBehavior; QuackBehavior quackBehavior; protected void setFlyBehavior(FlyBehavior flyBehavior) { this.flyBehavior = flyBehavior; } protected void setQuackBehavior(QuackBehavior quackBehavior) { this.quackBehavior = quackBehavior; } protected abstract void swim(); protected abstract void display(); protected void performFly() { flyBehavior.fly(); } protected void performQuack() { quackBehavior.quack(); } }
DecoyDuck
package com.singland.dp.strategy; public class DecoyDuck extends Duck { @Override protected void swim() { System.out.println("Decoy duck swim"); } @Override protected void display() { System.out.println("Decoy duck display"); } }
RubberDuck
package com.singland.dp.strategy; public class RubberDuck extends Duck { @Override protected void swim() { System.out.println("Rubber duck swim"); } @Override protected void display() { System.out.println("Rubber duck display"); } }
MyTest
package com.singland.dp.strategy; import org.junit.Test; public class MyTest { @Test public void testDecoyDuck() { Duck decoyDuck = new DecoyDuck(); decoyDuck.setFlyBehavior(new FlyNoWay()); decoyDuck.setQuackBehavior(new MuteQuack()); decoyDuck.display(); decoyDuck.swim(); decoyDuck.performFly(); decoyDuck.performQuack(); Duck rubberDuck = new RubberDuck(); rubberDuck.setFlyBehavior(new FlyNoWay()); rubberDuck.setQuackBehavior(new Quack()); rubberDuck.display(); rubberDuck.swim(); rubberDuck.performFly(); rubberDuck.performQuack(); } }
在这个例子中使用到了OO设计原则中的一条:把可变部分跟非可变部分分离开来并对可变部分进行封装。
所有的鸭子都有自己的形状并且能够游泳,但不是所有的样子都能够叫和飞,所以我们把叫和飞这两个行为跟鸭子本身的显示和游泳的行为分离开来并进行封装,这样FlyBehavior和QuackBehavior的具体实现可以多样化,具体的鸭子可以得到具体的飞和叫的行为,面向接口编程的好处就体现出来了。