介绍

将类中经常改变或者可能改变的部分提取成一个抽象策略接口类,然后在类中包含这个对象的实例,这样类实例在运行时就可以随意调用实现了这个接口的类的行为;

UML结构图

Image.png

  1. 环境类:Context,上下文角色,用一个ConcreteStrategy具体策略类来配置,持有Strategy对象并维护对Strategy对象的引用。可定义一个接口来让Strategy访问它的数据;
  2. 抽象策略类:Strategy,定义所有支持的策略公共接口。Context使用这个接口来调用某ConcreteStrategy定义的业务方法;
  3. 具体策略类:ConcreteStrategy,Strategy接口的具体实现业务类;

    优点缺点以及使用场景

    优点:可以动态改变对象的行为;
    缺点:会产生很多策略类,同时客户端必须知道所有的策略类,并自行决定使用哪个策略类;
    使用场景:

  4. 应用程序需要实现特定的功能服务,而该程序有多种实现方式使用,所有需要动态地在几种算法中选择一种;

  5. 一个类定义了多种行为算法,并且这些行为在类中的操作以多个条件语句的形式出现,就可以将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。

    代码实现

  • 抽象策略类:Strategy

    1. @Setter
    2. @Getter
    3. public abstract class OperationStrategy {
    4. /**
    5. * 数据1
    6. */
    7. double num_1;
    8. /**
    9. * 数据2
    10. */
    11. double num_2;
    12. /**
    13. * 抽象算法方法
    14. * @return
    15. */
    16. public abstract BigDecimal getResult();
    17. }
  • 环境类:Context

    1. public class OperationContext {
    2. /**
    3. * 声明一个策略对象
    4. */
    5. OperationStrategy operationStrategy = null;
    6. /**
    7. * 根据传递过来的字符串加载不同的策略具体类
    8. *
    9. * @param type
    10. */
    11. public OperationContext(String type, double num_1, double num_2) {
    12. switch (type) {
    13. case "-":
    14. operationStrategy = new SubOperationStrategy();
    15. break;
    16. case "+":
    17. operationStrategy = new AddOperationStrategy();
    18. break;
    19. case "*":
    20. operationStrategy = new MulOperationStrategy();
    21. break;
    22. case "/":
    23. operationStrategy = new DivOperationStrategy();
    24. break;
    25. default:
    26. System.out.println("非法操作!!");
    27. break;
    28. }
    29. operationStrategy.setNum_1(num_1);
    30. operationStrategy.setNum_2(num_2);
    31. }
    32. public BigDecimal getResult() {
    33. return operationStrategy.getResult();
    34. }
    35. }
  • 具体的策略实现类 ```java /**

  • @author xulihua
  • @date 2021/1/7 10:55
  • 加法策略实现类 */ public class AddOperationStrategy extends OperationStrategy{ @Override public BigDecimal getResult() {
    1. return new BigDecimal(getNum_1() + getNum_2());
    } }

/**

  • @author xulihua
  • @date 2021/1/7 11:25
  • 除法策略实现类 */ public class DivOperationStrategy extends OperationStrategy { @Override public BigDecimal getResult() {
      if (getNum_2() == 0){
          try {
              throw new Exception("除数不能为0");
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
      return new BigDecimal(getNum_1() / getNum_2()).setScale(2,BigDecimal.ROUND_HALF_UP);
    
    } }

/**

  • @author xulihua
  • @date 2021/1/7 11:36
  • 乘法策略实现类 */ public class MulOperationStrategy extends OperationStrategy { @Override public BigDecimal getResult() {
      // 保留两位小数
      return new BigDecimal(getNum_1() * getNum_2()).setScale(2,BigDecimal.ROUND_HALF_UP);
    
    } }

/**

  • @author xulihua
  • @date 2021/1/7 11:24 减法策略实现类 / public class SubOperationStrategy extends OperationStrategy { @Override public BigDecimal getResult() {
      return new BigDecimal(getNum_1() - getNum_2());
    
    } } ```
  • 测试 ```java /**
  • @author xulihua
  • @date 2021/1/7 10:16 */ public class Demo2Test { public static void main(String[] args) {
      /**
       * 算法符号
       */
      String type="*";
      /**
       * 数据1
       */
      double num_1=5.60;
      /**
       * 数据2
       */
      double num_2=6.60;
      // 通过上下文对象加载到相应的策略
      OperationContext context=new OperationContext(type,num_1,num_2);
      // 计算结果
      BigDecimal result = context.getResult();
      System.out.println("计算结果为:"+result);
    
    } } ```