一.设计模式入门--策略模式
1. 先看一个小例子
-------------------
父类:鸭
行为:【样子()】,【游泳()】,【呱呱叫()】
子类:绿头鸭,红头鸭
下面要做一些修改
修改1:给鸭加个【 飞()】的方法,做法是在父类里加一个【飞()】
修改2:加一个子类,橡皮鸭
结果发现,橡皮鸭是不会飞,所以在橡皮鸭中,要把飞(),这个方法重写一下,让它不会飞。
这样就发现,每在父类中新加一个可能会变化的方法,都会影响到子类,看是不是要重写。
当子类变多的时候,这种改动会非常庞大。
所以,在父类中加入一个会变化的方法,这种设计非常不好。
-------------------
结论:
所以像飞这种会变化的行为,应该把它从鸭类中分离出来,建立一个新类来代表这个行为。
这里要用到第二个设计原则:针对接口编程,而不是针对实现编程。
以前的做法:
行为由父类鸭的实现,或是继承某个接口,由子类实现,这样就会被实现绑死。
现在的做法:
定义一个【飞接口】,由具体的【会飞类】和【不会飞类】来实现。
解释一下针对接口编程这个概念
针对接口编程真正的意思是针对超类编程,这个也是对多态的运用。
更明确的说,超类的变量声明应该是超类型,可以是抽象类或是接口。
下面谈谈具体如何实现上面的【飞()】这个行为:
1. 首先得有一个【飞()】的接口,FlyBehavior
2. 有两个类实现这个接口,CanFly,CanNotFly,这样【飞()】和鸭子类就没有关系了
下来整合鸭子的行为
关键在于:鸭子现在将飞这个动作委托别人来处理,而不是使用定义在Duck类中的飞行方法。
具体做法:
A.在Duck类中,加入一个实例变量,FlyBehavior flyBehavior;
B.然后在Duck类中加一个方法
publicvoidperformFly(){
flyBehavior.fly();
}
C. 在Duck类的子类的构造方法里
publicMallardDuck(){
flyBehavior = new CanNotFly();
}
得出一个设计原则:多用组合,少用继承。
到此,策略模式已经完成。
回顾一下策略模式的定义:它定义了算法族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。