策略模式

github: https://github.com/lymboy/DesignPattern/tree/master/src/main/java/com/lymboy/designpattern/strategy

是什么?(定义)

策略(Strategy)模式的定义:该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。

这算法体现了几个设计原则,第一、把变化的代码从不变的代码中分离出来;第二、针对接口编程而不是具体类(定义了策略接口);第三、多用组合/聚合,少用继承(客户通过组合方式使用策略)。

举个栗子

6af89bc8gw1f8odxt4z16j202t02x0si.jpg

假如你需要前往机场。 你可以选择乘坐公共汽车、 预约出租车或骑自行车。 这些就是你的出行策略。 你可以根据预算或时间等因素来选择其中一种策略。

strategycomic1zh.png

策略模式结构

策略模式包含如下角色:

  • Context: 环境类
  • Strategy: 抽象策略类
  • ConcreteStrategy: 具体策略类

structure.png

案例代码

Strategy.java 出行策略接口

public interface Strategy {

    /**
     * 解决问题方法
     */
    void doMethod();
}

TaxiStrategy.java 出租车策略

public class TaxiStrategy implements Strategy{

    @Override
    public void doMethod() {
        System.out.println("出租车。。。");
    }
}

TrainStrategy.java 坐火车策略

。。。

FlyStrategy.java 乘飞机策略

。。。

image20210226221846111.png

Client.java 客户端

public class Client {

    public static void main(String[] args) {
        Context context = new Context();
        // 传入不同的实现类可产生不同的结果
        // Strategy strategy = new FlyStrategy();
        Strategy strategy = new TrainStrategy();
        context.setStrategy(strategy);

        context.doMethod();
    }
}

image20210226222509909.png

策略模式优缺点

优点

  • 你可以在运行时切换对象内的算法。
  • 你可以将算法的实现和使用算法的代码隔离开来。
  • 你可以使用组合来代替继承。
  • 开闭原则。 你无需对上下文进行修改就能够引入新的策略。

缺点

  • 如果你的算法极少发生改变, 那么没有任何理由引入新的类和接口。 使用该模式只会让程序过于复杂。
  • 客户端必须知晓策略间的不同——它需要选择合适的策略。
  • 许多现代编程语言支持函数类型功能, 允许你在一组匿名函数中实现不同版本的算法。 这样, 你使用这些函数的方式就和使用策略对象时完全相同, 无需借助额外的类和接口来保持代码简洁。

参考资料