策略(Strategy)模式的定义:该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。
策略模式的主要优点如下。
- 多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句。
- 策略模式提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。
- 策略模式可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的。
- 策略模式提供了对开闭原则的完美支持,可以在不修改原代码的情况下,灵活增加新算法。
- 策略模式把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离。
其主要缺点如下。
- 客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类。
- 策略模式造成很多的策略类。
其结构图如图 1 所示。
图1 策略模式的结构图
策略模式的实现代码如下:
创建接口
public interface FlyBehavior {
void Fly();
}
public interface QuackBehavior {
void Quack();
}
//具体策略类实现
public class BadFlyBehavior implements FlyBehavior {
@Override
public void Fly() {
System.out.println("Bad Fly!");
}
}
public class GoodFlyBehavior implements FlyBehavior {
@Override
public void Fly() {
System.out.println("Good Fly!");
}
}
public class GagaQuackBehavior implements QuackBehavior {
@Override
public void Quack() {
System.out.println("~~~Gaga~~~");
}
}
public class GegeQuackBehavior implements QuackBehavior {
@Override
public void Quack() {
System.out.println("~~~Gege~~~");
}
}
public class HahaQuackHehavior implements QuackBehavior {
@Override
public void Quack() {
System.out.println("~~~Haha~~~");
}
}
//抽象策略类
public abstract class Duck {
FlyBehavior mFlyBehavior;
QuackBehavior mQuackBehavior;
public Duck() {
}
public abstract void display();
public void Quack() {
mQuackBehavior.Quack();
}
public void Fly() {
mFlyBehavior.Fly();
}
public void setmFlyBehavior(FlyBehavior mFlyBehavior) {
this.mFlyBehavior = mFlyBehavior;
}
public void setmQuackBehavior(QuackBehavior mQuackBehavior) {
this.mQuackBehavior = mQuackBehavior;
}
}
//持有一个策略类的引用,最终给客户端调用
public class GreenHeadDuck extends Duck {
public GreenHeadDuck(){
mFlyBehavior=new GoodFlyBehavior();
mQuackBehavior=new GagaQuackBehavior();
}
@Override
public void display() {
System.out.println("Green head duck!");
}
}
public class RedHeadDuck extends Duck {
public RedHeadDuck() {
mFlyBehavior = new BadFlyBehavior();
mQuackBehavior = new HahaQuackHehavior();
}
@Override
public void display() {
System.out.println("Red head Duck!");
}
}
@Test
public void StratePatternTest() {
Duck greenHeadDuck = new GreenHeadDuck();
Duck redHeadDuck = new RedHeadDuck();
greenHeadDuck.display();
greenHeadDuck.Fly();
greenHeadDuck.Quack();
redHeadDuck.display();
redHeadDuck.Fly();
redHeadDuck.Quack();
}
输出结果:
在抽象策略类中为继承提供了改变行为的方法。
@Test
public void StratePatternTest() {
Duck greenHeadDuck = new GreenHeadDuck();
Duck redHeadDuck = new RedHeadDuck();
greenHeadDuck.display();
greenHeadDuck.Fly();
greenHeadDuck.Quack();
redHeadDuck.display();
redHeadDuck.Fly();
redHeadDuck.Quack();
System.out.println(" ");
System.out.println("改变行为后");
System.out.println(" ");
redHeadDuck.setmFlyBehavior(new GoodFlyBehavior());
redHeadDuck.Fly();
redHeadDuck.setmQuackBehavior(new GegeQuackBehavior());
redHeadDuck.Quack();
}
输出结果: