策略者模式,是要解决某类常规思想设计容易带来问题的问题。
请看如下案例:
1、模拟鸭子项目 2、项目的新需求 3、用OO原则解决新需求的不足 4、用策略模式来新需求解决 5、重新设计模拟鸭子项目 6、总结策略模式定义
策略模式原理
1、从项目"模拟鸭子游戏"开始 2、从OO的角度设计这个项目,鸭子超类,扩展超类: public abstract class Duck {
public void Quack() {
System.out.println("~~gaga~~");
}
public abstract void display();
public void swim() {
System.out.println("~~im swim~~");
}
}
模拟鸭子项目
1、GreenHeadDuck继承Duck : public class GreenHeadDuck extends Duck {
@Override
public void display() {
System.out.println("**GreenHead**");
}
}
2、同理可有RedHeadDuck等
模拟鸭子项目
1、应对新的需求,看看这个设计的可扩展性 1)添加会飞的鸭子 2、OO思维里的继承方式解决方案是: public abstract class Duck {
...;
public void Fly() {
System.out.println("~~im fly~~");
}
}; 问题来了,这个Fly让所有子类都会飞了,这是不科学的。 继承的问题:对类的局部改动,尤其超类的局部改动,会影响其他部分。影响会有溢出效应
项目的新需求
1、继续尝试用OO原理来解决,覆盖:
public class GreenHeadDuck extends Duck { ...; public void Fly()
{ System.out.println("~~no fly~~"); } }
2、又有新需求,石头鸭子,填坑:
public class StoneDuck extends Duck { ....
};
超类挖的一个坑,每个子类都要来填,增加工作量,复杂度O(N^2)。不是好的设计方式
用OO原则解决新需求的不足
需要新的设计方式,应对项目的扩展性,降低复杂度:
1)分析项目变化与不变部分,提取变化部分,抽象成接口+实现;
2)鸭子哪些功能是会根据新需求变化的?叫声、飞行...
用策略模式来新需求解决
1、接口:
1)
public interface FlyBehavior {
void fly();
}
2)
public interface QuackBehavior {
void quack();
};
3)好处:新增行为简单,行为类更好的复用,组合更方便。既有继承带来的复用好处,没 有挖坑
用策略模式来新需求解决
1、重新设计的鸭子项目:
public abstract class Duck {
FlyBehavior mFlyBehavior;
QuackBehavior mQuackBehavior;
public Duck() {
}
public void Fly() {
mFlyBehavior.fly();
}
public void Quack() {
mQuackBehavior.quack();
}
public abstract void display();
}
重新设计模拟鸭子项目
1、绿头鸭、石头鸭: public class GreenHeadDuck extends Duck { public GreenHeadDuck() { mFlyBehavior = new GoodFlyBehavior(); mQuackBehavior = new GaGaQuackBehavior(); } @Override public void display() {...} } 2、策略模式:分别封装行为接口,实现算法族,超类里放行为接口对象,在子类里具体设 定行为对象。原则就是:分离变化部分,封装接口,基于接口编程各种功能。此模式让行为 算法的变化独立于算法的使用者。
继承的问题:对类的局部改动,尤其是超类的局部改动,会影响其他部分,影响会有溢出效应:
理解一:策略(Strategy)模式是行为模式之一,它对一系列的算法加以封装,为所有算法定义一个抽象的算法接口,并通过继承该抽象算法接口对所有的算法加以封装和实现,具体的算法选择交由客户端决定(策略)。策略模式主要用来平滑地处理算法的切换。
理解二:策略模式分别封装行为接口,实现算法组,超类里面放行为接口对象,子类里面具体设定为对象。原则就是:分离变化部分,封装接口,基于接口编程各种功能,此模式让行为算法的变化,独立于算法的使用者。