策略模式定义是:定义算法族,分别封装起来,让它们之间可以互相替换,算法的变化独立于使用算法的客户。
我们来模拟一种情形来理解这句话。有一群鸭子,有各种颜色的鸭,他们有的会飞,有的不会飞,飞的姿态也更不相同。此时如果在每只鸭子里分别定义飞的姿态,那有成千上万中鸭子的时候就会累死。这时我们考虑使用设计模式来实现下它。
- 设计原则中第一条:找出应用中可能需要变化之处,把它们独立出来。当然这里我们独立的就是会变化的飞行为。
- 设计模式第二条:针对接口编程,而不是针对实现编程。所以到这里我们写出如下飞的代码:
public interface FlyBehavior {
public void fly();
}
定义了接口类,再定义实现类,会简单,只定义会飞和不会飞行为:
public class NoFly implements FlyBehavior {
@Override
public void fly() {
// TODO Auto-generated method stub
System.out.println("this duck can not fly");
}
}
public class CanFly implements FlyBehavior{
@Override
public void fly() {
// TODO Auto-generated method stub
System.out.println("this duck can fly");
}
}
以上就是针对==接口编程==。
- 设计原则第三条:多用组合,少用继承。那我们也来运用下。定义鸭子的抽象类:
public abstract class Duck {
FlyBehavior flyBehavior;
public abstract void disply();
public void performFly(){
flyBehavior.fly();
}
public FlyBehavior getFlyBehavior() {
return flyBehavior;
}
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
}
其中它有一个FlyBehavior对象,组合了飞的行为。
好了,接下来就是实体鸭子,只要继承超类就可以了。
public class RedDuck extends Duck{
public RedDuck() {
// TODO Auto-generated constructor stub
flyBehavior = new NoFly();//默认不会飞
}
@Override
public void disply() {
// TODO Auto-generated method stub
System.out.println("the color is red");
}
}
红鸭不会飞,再来一只黑鸭会飞:
public class BlackDuck extends Duck{
public BlackDuck() {
// TODO Auto-generated constructor stub
flyBehavior = new CanFly();//默认不会飞
}
@Override
public void disply() {
// TODO Auto-generated method stub
System.out.println("the color is black");
}
}
public class Main {
public static void main(String[] args){
Duck duck = new RedDuck();
duck.performFly();
duck.disply();
duck.setFlyBehavior(new CanFly());
duck.performFly();
System.out.println("-----------------");
Duck duck2 = new BlackDuck();
duck2.performFly();
duck2.disply();
duck2.setFlyBehavior(new NoFly());
duck2.performFly();
}
}
好处己经非常明显了,要什么飞行行为只要在运行时进行替换就可以了。这种模式的好处:实现不会被绑死在子类中,使用接口,可以运行时替换。看上它的UML图:
[设计模式]Strategy策略模式