设计模式:025_策略模式

75 阅读2分钟

策略模式

策略模式(Strategy Pattern),定义一系列算法,并将每个算法封装起来,使它们可以相互替换,不同的策略使用不同的算法,且算法的变化不会影响使用算法的客户端。

作用

  • 算法可以自由切换
  • 避免使用多重条件判断(如果不用策略模式可能会使用多重条件语句,不利于维护)
  • 扩展性良好,增加一个策略只需实现接口即可

缺点

  • 策略类数量会增多,每个策略都是一个类,复用的可能性很小
  • 所有的策略类都需要对外暴露

适用场景

  • 多个类只有算法或行为上稍有不同的场景
  • 算法需要自由切换的场景
  • 需要屏蔽算法规则的场景

类图

策略模式类图.png

  • 上下文(Context)角色:起承上启下封装作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。
  • 抽象策略(Strategy)角色:策略、算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性。
  • 具体策略(ConcreteStrategy)角色:实现抽象策略中的操作,该类含有具体的算法。

代码表达

// 抽象策略(Strategy)角色
public interface FlyBehavior {
    void fly();
}

public interface QuackBehavior {
    void quack();
}
// 具体策略(ConcreteStrategy)角色
public class GoodFlyBehavior implements FlyBehavior {
    @Override
    public void fly() {
        System.out.println("GoodFly");
    }
}

public class NoFlyBehavior implements FlyBehavior {
    @Override
    public void fly() {
        System.out.println("NoFly");
    }
}

public class BadFlyBehavior implements FlyBehavior {
    @Override
    public void fly() {
        System.out.println("BadFly");
    }
}

public class HighQuackBehavior implements QuackBehavior {
    @Override
    public void quack() {
        System.out.println("HighQuack");
    }
}

public class LowQuackBehavior implements QuackBehavior {
    @Override
    public void quack() {
        System.out.println("LowQuack");
    }
}
// 上下文(Context)角色
public abstract class Duck {
    // 聚合所有的策略类
    protected FlyBehavior flyBehavior;
    protected QuackBehavior quackBehavior;

    public void setFlyBehavior(FlyBehavior flyBehavior) {
        this.flyBehavior = flyBehavior;
    }

    public void setQuackBehavior(QuackBehavior quackBehavior) {
        this.quackBehavior = quackBehavior;
    }

    public abstract void display();

    public void swim() {
        System.out.println("Duck swim");
    }

    public void fly() {
        if (flyBehavior != null) {
            flyBehavior.fly();
        }
    }

    public void quack() {
        if (quackBehavior != null) {
            quackBehavior.quack();
        }
    }
}

// 上下文(Context)角色具体实现类
public class WildDuck extends Duck {
    public WildDuck() {
        flyBehavior = new GoodFlyBehavior();
        quackBehavior = new HighQuackBehavior();
    }

    @Override
    public void display() {
        System.out.println("WildDuck display");
    }
}

public class PekingDuck extends Duck {
    public PekingDuck() {
        flyBehavior = new BadFlyBehavior();
        quackBehavior = new LowQuackBehavior();
    }

    @Override
    public void display() {
        System.out.println("PekingDuck display");
    }
}

public class ToyDuck extends Duck {

    public ToyDuck() {
        flyBehavior = new NoFlyBehavior();
    }

    @Override
    public void swim() {
        System.out.println("ToyDuck can not swim");
    }

    @Override
    public void quack() {
        System.out.println("ToyDuck can not quack");
    }

    @Override
    public void display() {
        System.out.println("ToyDuck display");
    }
}

客户端调用

WildDuck wildDuck = new WildDuck();
wildDuck.display();
wildDuck.fly();
wildDuck.quack();
PekingDuck pekingDuck = new PekingDuck();
pekingDuck.display();
pekingDuck.fly();
pekingDuck.quack();
ToyDuck toyDuck = new ToyDuck();
toyDuck.display();
toyDuck.fly();
toyDuck.quack();
// 动态改变对象的行为策略
pekingDuck.setFlyBehavior(new GoodFlyBehavior());
pekingDuck.setQuackBehavior(new HighQuackBehavior());
pekingDuck.display();
pekingDuck.fly();
pekingDuck.quack();