定义了算法族,分别封装起来,可以互相替换,此模式让算法的变化独立于使用算法的人。这就是策略模式!(后面会解释定义)
再说说关于策略模式的一些原则,带着这些原则去看问题会容易理解一点。
涉及的原则有三个:
1.找出应用可能需要变化之处,把它独立出来,不要和那些不需要变化的代码混在一起。(即把会变化的部分取出来并“封装”起来,以便以后可以轻易的改动和扩展此部分,好让其它部分不受影响。)换一句话说,如果每次新需求来,都会使某方面的代码发生变化,那你就可以确定,这部分代码需要被抽取出来,和其它稳定的代码有所区分。
2.针对接口编程(针对超类型编程),而不是针对实现编程。
3.多用组合,少用继承
下面就看一个例子:
有一个Duck的抽象类(即所有鸭子的超类),Duck的些共同的行为比如:吃,游泳,飞,展示(让别人看看自己有多帅)等;
这时有个WhiteDuck(普通鸭)和WildDuck(野生鸭)都继承了Duck,会发现普通的鸭不会飞,但它继承了Duck不会飞都变会飞了!你可能觉得我在WhiteDuck重写该方法让它不会飞不就行了,要是现在你项目理由成百上千个xxxDuck,那不是要每个xxxDuck都要重写。突然又新来了一个RubberDuck(橡皮鸭)除了游泳和展示,既不会吃也不会飞!在后来有个新需求说鸭子有会叫的功能,于是在Duck类上加个quack行为。最后导致动一牵全身,让所有的Duck子类都会叫不管是RubberDuck还是...
该怎么办好呢!?这就要用到我们的第一和第二个原则:
将所有不确定的行为,抽取独立出来用接口封装表示某个行为,每个行为都有各自的具体实现。然后在超类定义行为(接口)变量,在超类的方法中调用接口的方法。在所有的Duck子类中知道具体的行为。
public interface FlyBehavior {//飞的行为
void fly();
}
飞的具体实现
public class NoFlyBehavior implements FlyBehavior {//不会飞的行为
@Override
public void fly() {
System.out.println("--NoFly--");
}
}
public class GoodFlyBehavior implements FlyBehavior {//飞的好的行为
@Override
public void fly() {
System.out.println("--GoodFly--");
}
}
public class BadFlyBehavior implements FlyBehavior {//飞的差的行为
@Override
public void fly() {
System.out.println("--BadFly--");
}
}
public interface QuackBehavior {//叫的行为
void quack();
};
叫的具体实现
public class NoQuackBehavior implements QuackBehavior {//不会叫的行为
@Override
public void quack() {
System.out.println("__NoQuack__");
}
}
public class QuackGoodBehavior implements QuackBehavior {//叫的好的行为
@Override
public void quack() {
System.out.println("__QuackGood__");
}
}
上述的这些行为的具体实现称之为算法族。
Duck类:
public abstract class Duck {
protected FlyBehavior flyBehavior;
protected QuackBehavior quackBehavior;
public void fly() {
flyBehavior.fly();//调用接口飞的行为
}
public void quack() {
quackBehavior.quack();//调用接口叫的行为
}
public abstract void display();
public void SetQuackBehavoir(QuackBehavior qb) {
quackBehavior = qb;
}
public void SetFlyBehavoir(FlyBehavior fb) {
flyBehavior = fb;
}
}
Duck的子类:
public class WhiteDuck extends Duck {
public WhiteDuck() {
flyBehavior = new NoFlyBehavior();//指定具体的行为,(面向接口(超类)编程)
quackBehavior = new QuackGoodBehavior();
}
@Override
public void display() {
System.out.println("普通的鸭");
}
}
public class WildDuck extends Duck {
public WildDuck() {
flyBehavior = new GoodFlyBehavior();//指定具体的行为
quackBehavior = new BadQuackBehavior();
}
@Override
public void display() {
System.out.println("野生的鸭");
}
}
演示最终结果
public class StimulateDuck {
public static void main(String[] args) {
Duck whiteDuck = new WhiteDuck();
Duck wildDuck = new WildDuck();
whiteDuck.fly();
whiteDuck.quack();
whiteDuck.display();
wildDuck.fly();
wildDuck.quack();
wildDuck.display();
wildDuck.SetFlyBehavoir(new GoodFlyBehavior());
wildDuck.fly();
}
}
以上是个人的理解,说的可能不是很好,有什么不对的望各位猿兄们指正。