策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。也就是把算法封装起来,方便改变,减少耦合。
组合:把两个类结合起来使用。增加弹性,不仅可以将算法族封装成类,更可以“在运行时动态的地改变行为”,只要组合的行为对象符合接口标准就行了。
比如一个抽象类,加一个接口,接口封装各种方法,抽象类就只被继承主要的公共功能,让其他子类达到更好的代码重用,和实现其他方法。
设计原则:
1.找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
(封装变化的部分,方便修改和扩展)
2.针对接口编程,而不是针对实现编程,
利用接口代表方法,可以实现多个接口,而继承只能有一个,松耦合,高内聚。
(“有一个”和“是一个”)有一个可以实现接口,动态的绑定或者分离。是一个就是继承,绑定住了,不方便维护。
3.多用组合,少用继承。
需求:一个鸭子模型,公共功能是游泳,会变化的功能是飞;
解决:1.创建一个抽象鸭类 其中有一个 FlyBehavior 接口,这样的行为就是一个组合。
package com.CeNveMoShiTest;/** * 策略模式:将一族算放封装起来,互相替换,并且对客户没有影响 * 实现:一个抽象鸭类,一个飞行接口,一个木头鸭类,一个会飞的鸭类 *声明行为接口类型的两个变量,给鸭子子类继承 */public abstract class Duck { FlyBehavior flyBehavior; //飞行行为,都是接口 方便组合 public Duck() { } public void setFlyBehavior(FlyBehavior fb){ flyBehavior = fb; } public abstract void display(); public void performFly() { flyBehavior.fly(); } public void swim(){ System.out.println("都会游泳"); }}
2.飞行接口的两个不同实现,会飞和不会飞的两个类
package com.CeNveMoShiTest;/** * Created by Administrator on 2017/10/13 0013. */public interface FlyBehavior { public void fly();}package com.CeNveMoShiTest;/** * Created by Administrator on 2017/10/13 0013. */public class FlyNoWay implements FlyBehavior { @Override public void fly() { System.out.println("不会灰"); }}package com.CeNveMoShiTest;/** * Created by Administrator on 2017/10/13 0013. */public class FlyWithWings implements FlyBehavior { @Override public void fly() { System.out.println("会灰"); }}
3.建一个模型鸭的子类,继承父类,并且使用组合的方法调用接口的实现方法;而不需要重新实现接口
package com.CeNveMoShiTest;/** * Created by Administrator on 2017/10/13 0013. */public class ModelDuck extends Duck { @Override public void display() { System.out.println("一只模型鸭子"); } public static void main(String[] args) { Duck du = new ModelDuck(); du.display(); du.swim(); du.setFlyBehavior(new FlyWithWings()); // du 调用父类的set方法,参数是创建一个接口的实现类,实现该接口的方法 du.performFly(); //才会实现 du.setFlyBehavior(new FlyNoWay()); du.performFly(); }}