声明:
本节内容主要来自Head First
好吧,现在带你进入策略模式的地盘
参考:
http://www.tuicool.com/articles/bU73em
简图:
【what】
策略模式是什么
策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
类图
组成
—抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
—具体策略角色:包装了相关的算法和行为。
—环境角色:持有一个策略类的引用,最终给客户端调用。
Context(应用场景):
1、需要使用ConcreteStrategy提供的算法。
2、 内部维护一个Strategy的实例。
3、 负责动态设置运行时Strategy具体的实现算法。
4、负责跟Strategy之间的交互和数据传递。
Strategy(抽象策略类):
1、 定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,Context使用这个接口调用不同的算法,一般使用接口或抽象类实现。
ConcreteStrategy(具体策略类):
2、 实现了Strategy定义的接口,提供具体的算法实现。
【How】
讲故事是最好的开场白,源自于Head First 的例子华丽登场啦
【鸭子的故事】
这个要从鸭子的故事开始,唔,这个故事说来话长,不过挺通俗易懂而且有趣的~~
我们把 会嘎嘎叫、会游泳、会飞……的一类动物统称为鸭子~~
话不多说,直接看图吧:
这个优化后的图很棒,结构很美。
【敲黑板--划重点】
这个案例中最牛逼的地方是把易变的fly() 和 quack() 抽象出来封装成两个接口,然后这两个接口作为抽象对象的属性
最后针对这两个接口,下面分别若干实现子类。
鸭子类,这是一个抽象超类
public abstract class Duck {
protected FlyBehavior flyBehavior;
protected QuackBehavior quackBehavior;
public void setFlyBehavior(FlyBehavior flyBehavior){
this.flyBehavior=flyBehavior;
}
public void QuackBehavior(QuackBehavior quackBehavior){
this.quackBehavior=quackBehavior;
}
public abstract void dispaly();//鸭子描述
/**
* 委托给行为类
*/
public void performFly(){//鸭子飞
flyBehavior.fly();
}
public void performQuack(){//鸭子叫
quackBehavior.quack();
}
}
将飞行和嘎嘎叫两个可变行为单独抽离出来,作为接口
public interface FlyBehavior {
void fly();
}
public interface QuackBehavior {
void quack();
}
绿头鸭
public class MallardDuck extends Duck{
public MallardDuck(){
//叫的职责被委托给Quack对象
quackBehavior = new Quack();
//飞的职责被委托给FlyWithWings
flyBehavior = new FlyWithWings();
}
@Override
public void display() {
System.out.println("I'm a real Mallard duck");
}
}
【why】
为什么需要策略模式?
策略模式定义了算法族,分别分装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
【where & when】
应用的场合? 时间?
应用场景:
1、 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
2、 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。
3、 对客户隐藏具体策略(算法)的实现细节,彼此完全独立。
好吧,一提起策略模式,我脑海中马上就浮现出“鸭子的故事”,这是个经典的优秀的案例,最好还能画出大致的类图~~
哇,鸭子的故事太感人了~~
老规矩,上小和尚镇楼。