策略模式:策略模式定义了算法族,分别封装起来,让他们可以相互替换,此模式让算法的变化独立于使用算法的客户。
设计原则:
- 找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混在一起。以便以后轻松的更改或扩充此部分,而不影响不需要变化的其他部分
- 针对接口编程而不是针对实现编程。实际的实现不会被绑定,调用时只知道调用的接口,而无需知道具体的实现方式
- 多用组合,少用继承。使用组合有很大的弹性,可以在运行时动态改变行为
要点:
- 良好的OO设计必须遵循可复用,可拓展,可维护
- 大部分模式允许系统的局部改变独立于其他部分
- 把系统中会变化的部分抽出来进行封装
举例:
- 基础的鸭子类有方法quack,swim,display,fly等方法,使用抽象基类表示,不同种类的鸭子继承至该基类。
-
但是quack与fly方法对于不同的鸭子有不同的实现,无法将基类中的实现用于所有子类,并且子类具体行为表示不明确
- 继承不可行,使用借口呢,使用flyable,quackable借口实现
- 代码无法复用,对于每类鸭子都需要实现quack和fly,造成大量的重复代码,并且当一种飞行方式改变时,该飞行方式的所有鸭子类都需要修改
- 将变化的行为从鸭子类中取出来。在Duck基类中添加两个实例变量,flyBehavior和quackBehavior接口类型,行为中的不同内容实现相同接口,针对接口编程,而不是针对实现编程,需要修改干个功能点使用接口,实现方式灵活多变。
核心思想:将is-a 转换为has-a.
基本的思路:将一些原先要继承的方法,以接口的方式抽象出来,然后再以实现该接口的方式定义一些类以完成实际能力的实现;同时在基类中以组合的方式将该接口的实例放入基类,基类同时提供设置这个实例的接口以及这个方法的封装,子类继承基类是对这些接口实例进行设置即可。
代码实现:
public interface FlyBehavior { public void fly(); } // 飞 public class FlyWithWings implements FlyBehavior{ public void fly() { System.out.println("正在用翅膀飞行"); } } // 不飞 public class FlyNoWay implements FlyBehavior{ public void fly() { System.out.println("不会飞"); } }
1 public interface QuackBehavior { 2 public void quack(); 3 } 4 // 嘎嘎叫 5 public class Quack implements QuackBehavior. { 6 public void quack() { 7 System.out.println("嘎嘎叫"); 8 } 9 } 10 // 吱吱叫 11 public class Squeak implements QuackBehavior{ 12 public void quack() { 13 System.out.println("吱吱叫"); 14 } 15 } 16 // 不叫 17 public class MuteQuack implements QuackBehavior{ 18 public void quack() { 19 System.out.println("不会叫"); 20 } 21 }
1 public abstract class Duck { 2 // 默认的行为 3 FlyBehavior flyBehavior; 4 QuackBehavior quackBehavior; 5 6 public Duck() { 7 } 8 public void setFlyBehavior(FlyBehavior fb) { 9 flyBehavior = fb; 10 } 11 public void setQuackBehavior(QuackBehavior qb) { 12 quackBehavior = qb; 13 } 14 abstract void display(); 15 public void performFly() { 16 flyBehavior.fly(); 17 } 18 public void performQuack() { 19 quackBehavior.quack(); 20 } 21 public void swim() { 22 System.out.println("正在游泳~~"); 23 } 24 }
1 // 野鸭 2 public class MallardDuck extends Duck { 3 public MallardDuck() { 4 quackBehavior = new Quack(); 5 flyBehavior = new FlyWithWings(); //这里也可以使用setFlyBehavior方法,下同! 6 } 7 public void display() { 8 System.out.println("绿头鸭"); 9 } 10 } 11 // 红头鸭 12 public class RedHeadDuck extends Duck { 13 public RedHeadDuck() { 14 flyBehavior = new FlyWithWings(); 15 quackBehavior = new Quack(); 16 } 17 public void display() { 18 System.out.println("红头鸭"); 19 } 20 } 21 // 橡皮鸭 22 public class RubberDuck extends Duck { 23 public RubberDuck() { 24 flyBehavior = new FlyNoWay(); 25 quackBehavior = new Squeak(); 26 } 27 public void display() { 28 System.out.println("橡皮鸭"); 29 } 30 }
1 public class MiniDuckSimulator { 2 3 public static void main(String[] args) { 4 5 MallardDuck mallard = new MallardDuck(); 6 RubberDuck rubberDuckie = new RubberDuck(); 7 RedHeadDuck redHeadDuck = new RedHeadDuck(); 8 9 mallard.performQuack(); 10 rubberDuckie.performQuack(); 11 redHeadDuck.performQuack(); 12 } 13 }