前言
爱因斯坦说过这样一句话:如果你不能简单地解释一样东西,说明你没真正理解它。(ps:如果爱因斯坦没说过,那可能是鲁迅说的......)所以,我写不出这篇文章。我就不打算再学下去,我要继续学策略模式,指导能简单地解释它。
策略模式定义
定义了算法族,分别封装起来,让它们之间可以互相替换,此模式
让算法的变化独立于使用算法的客户
。
例子
假如现在要做一款鸭子应用,作为一个OO程序员,这可不是一件难事。设计一个鸭子超类,再让它有'呱呱'叫、游泳的方法。
public class Duck{
public void quck(){ // some code }
public void swim(){ // some code }
//other function...
}
然后让什么可达鸭、唐老鸭去继承超类。接着我们要做一件有趣的事,让鸭子会飞。在Duck类上加 fly()
方法。但是可怕的问题发生了......所有鸭子会飞了,包括'橡皮鸭'也在飞,而且诱饵鸭不会叫也不会飞。这可不是我们希望看到的。
利用接口如何?
把'飞'、'呱呱叫'分离出来分别做成Flyable接口跟Quackable接口。但是java接口不具有实现代码的功能。难道还要给每个角色都去实现飞的功能,这样做就没有使代码达到"复用"的效果。
该怎么做呢?!
先让我们回顾下‘策略’的定义 ,“...让算法的变化独立于使用算法的客户”。我们把'飞'啊、'呱呱叫'啊独立开来,只留下不需要变化的。做成一些行为接口,然后让Duck类用过行为类的类型。
public interface FlyBehavior{
fly();
}
//会飞的行为类
public class FlyWithWings implements FlyBehavior ()
{
public void fly()
{
System.out.println("i can flying...");
}
}
//不会飞的行为类
public class FlyNoWay implements FlyBehavior ()
{
public void fly()
{
//nothing to do,can't fly
}
}
public interface QuckBehavior{
quack();
}
//呱呱叫行为类
public class Quack
{
//实现呱呱叫
}
public class Squeak
{
//橡皮鸭吱吱叫
}
//不会叫的...
现在我们将飞、叫delegate(委托)别人处理,而不是定义在Duck类中或者子类中。接着我们整理下代码。
public abstract class Duck
{
FlyBehavior flyBehavior;
QuckBehavior quckBehavior;
public void performFly()
{
flyBehavior.fly();
}
public void performQuck()
{
quckBehavior.quack();
}
}
写在后面的
让我们再次回归定义,“定义了算法族,分别封装起来”,在这个例子中就是飞的行为、叫的行为。“让算法的变化独立于使用算法的客户”,客户需要一个会飞的鸭子就实现飞接口再实现飞的方法。需要叫就同理,这样去独立于使用算法。
我写得哪里不好,请大神说出来,我会改正的。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。