基本介绍
- 策略模式中,定义算法蔟,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户
- 这算法体系了几个设计原则,第一:把变化的代码从不变的代码中分离出来;第二:针对接口编程而不是具体类(定义了策略接口),第三:多用组合/聚合,少用继承(客户通过组合方式使用策略)
- 说明:客户context,有对应的策略接口,至于需要使用到那个策略,可以在构造器中指定
代码示例
策略接口
public interface FlyBehavior {
void fly();
}
具体策略
public class GoodFlyBehavior implements FlyBehavior{
@Override
public void fly() {
System.out.println("飞行技术高超");
}
}
public class NoFlyBehavior implements FlyBehavior{
@Override
public void fly() {
System.out.println("不会飞");
}
}
public class BadFlyBehavior implements FlyBehavior{
@Override
public void fly() {
System.out.println("飞行技术不行");
}
}
策略对象适用抽象类
public abstract class Duck {
/**
* 策略接口
*/
FlyBehavior flyBehavior;
public void fly(){
if (flyBehavior != null){
flyBehavior.fly();
}
}
public FlyBehavior getFlyBehavior() {
return flyBehavior;
}
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
}
具体实现
public class ToyDuck extends Duck{
public ToyDuck() {
this.flyBehavior = new NoFlyBehavior();
}
}
public class WildDuck extends Duck{
public WildDuck() {
this.flyBehavior = new GoodFlyBehavior();
}
}
public class PekingDuck extends Duck{
public PekingDuck() {
this.flyBehavior = new BadFlyBehavior();
}
}
客户端调用
public class Client {
public static void main(String[] args) {
Duck pekingDuck = new PekingDuck();
pekingDuck.fly();
ToyDuck toyDuck = new ToyDuck();
toyDuck.fly();
WildDuck wildDuck = new WildDuck();
wildDuck.fly();
// 动态改变
pekingDuck.setFlyBehavior(new NoFlyBehavior());
pekingDuck.fly();
}
}
注意事项和细节
- 关键是:分析项目中变化部分和不变部分
- 核心思想:多用组合/聚合,少用基础,用行为类组合,而不是行为的继承,更有弹性
- 体现了“对修改关闭,对扩展开放“原则,客户端增加行为不用修改原有代码,只要添加一种策略(或者行为)即可,避免了使用多重转换语句(if-else)
- 提供了可以替换继承关系的办法:策略模式将算法封装在独立的Strategy类中使得你可以独立于其Context改变它,使他易于切换,易于理解,易于扩展
- 需要注意的是:每添加一个策略就要增加一个类,当策略过多是会导致类数目庞大