策略模式

模式名和分类

  • 策略模式:xxxStrategy
  • 分类:行为模式

意图

解决处理算法多变而程序设计改动需要小的矛盾。就是算法的增加和修改,程序的影响更小。

别名

xxxPolicy

动机

  • 解决多变的处理算法,而不愿意改动太多程序。
        面对经常变化的算法需求,可能是电商系统中多变的优惠需求,支付系统中可能是不同分类商户的处理方式,经常新增的邮件模板..等等。在算法不确定且多变,而我们只需要选择其中之一时,不妨考虑此模式。

  • 如果你的程序中用了过多的case,或者过多的if-else,目的是根据条件选择不同的处理算法。

  • 如果你的处理算法需要经常变动,需要时常新增。

  • 如果你需要根据不同的条件路由到不同的处理方式

结构

参与者

  • 抽象接口/类,它代表着一类问题的抽象表达。例如计算,加法计算,减法计算或是其他类计算,都是传入值得到结果。--Strategy
  • 具体处理算法类,它将实现/继承抽象的接口或类,作为真正的执行者。--Add、Substract、Multiply
  • 运行环境,它将保存上下文环境,真正的做出选择,根据条件选择具体的算法类处理问题。--Context

协作

  • 调用者创建运行环境类Context

  • 在context中聚合了Strategy接口

  • 当调用者执行Context.doOperation时,context选择具体的Strategy实现者来处理问题。

  • 调用端不需要直接耦合算法类,构建合适的context后,只需要调用Context.doOperation得到结果。

  • 增加算法:只需要实现Strategy接口,然后再调用方来构建对应的Context即可。

  • 替换算法:调用者构建不同的context,context即会调用算法。

  • 路由算法:可以再创建Context时通过构造函数由调用者指定具体的路由算法(案例代码就是这么做的),也可以传入选择条件让Context来根据条件选择具体的路由算法(例如工厂模式或者直接if-else判断)。

实现

  • 算法抽象类,代表一类的处理方法。
  • 上下文context作为模式的运行环境
  • 调用者,构建context时选择需要的算法,可能时构造函数注入,也可能时传入条件让context自己判断。

代码实例

https://www.runoob.com/design-pattern/strategy-pattern.html

如果有写得好的例子,为什么不能抄呢,毕竟你写得不一定有他好

模式案例

// Strategy.java 接口
public interface Strategy {
   public int doOperation(int num1, int num2);
}

// OperationAdd.java 具体策略:加法
public class OperationAdd implements Strategy{
   @Override
   public int doOperation(int num1, int num2) {
      return num1 + num2;
   }
}

// OperationSubstract.java 具体策略:减法
public class OperationSubstract implements Strategy{
   @Override
   public int doOperation(int num1, int num2) {
      return num1 - num2;
   }
}

// OperationMultiply.java 具体策略:乘法
public class OperationMultiply implements Strategy{
   @Override
   public int doOperation(int num1, int num2) {
      return num1 * num2;
   }
}


// Context.java 运行环境:保存策略的上下文
public class Context {
   private Strategy strategy;
 
   public Context(Strategy strategy){
      this.strategy = strategy;
   }
 
   public int executeStrategy(int num1, int num2){
      return strategy.doOperation(num1, num2);
   }
}

// StrategyPatternDemo.java 调用者:使用策略。这里值得提一下,此处在构建context的时候直接由构造函数
// 指定了具体策略,但是我们在应用的时候,可以不这么简单粗暴。
// 跟不同的模式,例如工厂、抽象工厂、建造者模式之类的模式配合起来,可以更灵活,封装得更好。根据具体需要来选择
public class StrategyPatternDemo {
   public static void main(String[] args) {
      Context context = new Context(new OperationAdd());    
      System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
 
      context = new Context(new OperationSubstract());      
      System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
 
      context = new Context(new OperationMultiply());    
      System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
   }
}

已知应用

spring框架中:InstantiationStrategy

在spring框架中,没有找到好的实现Strategy的例子,在jmx中有提到,但是不够经典。在springMVC中,它的实现方式更多,但是用法多半不单单限于策略模式,或者说不能完美的展示这个模式,暂时不太愿意在这里详细展示。希望以后写到其他模式的时候,或者混合模式的时候能记起来,这里还留了一个空。但是...老话说得好“later equals never”。

posted @ 2019-07-10 10:25  undifinedException  阅读(257)  评论(0编辑  收藏  举报