策略模式是把程序不变的逻辑与可变的逻辑分别封装,让算法的变化独立于使用算法的客户,这样设计有很好的扩展性,可根据需求修改算法或增删都不会影响客户代码。
示例:设计鸭子
一、鸭子基础类
封装了鸭子的基础特性,包含了行为和特征,行为用接口的形式声明,不实现具体行为,鸭子的子类可动态设置行为,与鸭子本身解耦,特征用抽象方法来声明,是每个鸭子必有的特性。
public abstract class BaseDuck {
protected BaseFlyBehavior flyBehavior;
protected BaseQuackBehavior quackBehavior;
public void setFlyBehavior(BaseFlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
public void setQuackBehavior(BaseQuackBehavior quackBehavior) {
this.quackBehavior = quackBehavior;
}
/**
* 鸭子介绍
*/
public abstract void display();
/**
* 鸭子飞
*/
public void performFly() {
flyBehavior.flay();
}
/**
* 鸭子叫
*/
public void performQuack() {
quackBehavior.quack();
}
}
二、定义鸭子行为接口
新创建的所有行为都必须实现此接口,然后在覆盖的方法中实现具体的行为(算法)。
1.鸭子的飞行
public interface BaseFlyBehavior {
public void flay();
}
2.鸭子的叫唤
public interface BaseQuackBehavior {
public void quack();
}
三、实现鸭子的行为
都需实现BaseFlyBehavior、BaseQuackBehavior接口,然后在flay()、quack()中编写具体行为。
1.会飞
public class FlyWithWings implements BaseFlyBehavior {
@Override
public void flay() {
Log.i("==TAG==", "会飞");
}
}
2.不会飞
public class FlyNoWay implements BaseFlyBehavior {
@Override
public void flay() {
Log.i("==TAG==", "不会飞");
}
}
3.会嘎嘎叫
public class Quack implements BaseQuackBehavior {
@Override
public void quack() {
Log.i("==TAG==", "嘎嘎叫");
}
}
4.不会叫
public class MuteQuack implements BaseQuackBehavior {
@Override
public void quack() {
Log.i("==TAG==", "不会叫");
}
}
4.具备火箭动力
public class FlyRocketPowered implements BaseFlyBehavior {
@Override
public void flay() {
Log.i("==TAG==", "我具备了火箭动力");
}
}
三、实现多种类型的鸭子
1.绿头鸭
会嘎嘎叫,会飞
public class MallardDuck extends BaseDuck {
public MallardDuck(){
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
@Override
public void display() {
Log.i("==TAG==","我是绿头鸭");
}
}
2.模型鸭
不会叫,不会飞
public class ModelDuck extends BaseDuck {
public ModelDuck(){
quackBehavior = new MuteQuack();
flyBehavior = new FlyNoWay();
}
@Override
public void display() {
Log.i("==TAG==", "我是模型鸭");
}
}
四、生产鸭子
可以看到所有的鸭子都实现了鸭子基类,并用鸭子基类声明,这使得生产的多个鸭子有了很好的约束性,同时行为的分离封装保证了其很高的可扩展性,这样的设计能应对不断变化的需求,届时只需创建新的行为即可。
public class StrategyControl {
private static StrategyControl mInstance;
public static StrategyControl getInstance() {
if (mInstance == null) {
synchronized (StrategyControl.class) {
if (mInstance == null) {
mInstance = new StrategyControl();
}
}
}
return mInstance;
}
public void execute() {
//绿头鸭
BaseDuck mallardDuck = new MallardDuck();
mallardDuck.display();
mallardDuck.performQuack();
mallardDuck.performFly();
//模型鸭
BaseDuck modelDuck = new ModelDuck();
modelDuck.display();
modelDuck.performQuack();
modelDuck.performFly();
//模型鸭具备火箭动力
modelDuck.setFlyBehavior(new FlyRocketPowered());
modelDuck.performFly();
}
}