• 设计模式之策略模式


    • 场景

    一般情况下我们会想到使用if...else,如下代码。但是实际的业务场景肯定不止这四种,随着条件越来也来,代码就显得非常的臃肿和难以维护。(也可以使用switch来实现,这里就不赘述了)

    1. package com.example.designpattern.celuemoshi.old;
      
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;
      
      /**
       * @author shkstart
       * @create 2021-07-11 22:16
       */
      @RestController
      @RequestMapping("/testController")
      public class TestController {
      
          @RequestMapping("/arithmetic02")
          public double arithmetic02(String arithmeticType, int startNum, int endNum) {//arithmetic算术
              double result = 0.0;
              if (arithmeticType.equals("addition")) {
                  result = startNum + endNum;
              } else if (arithmeticType.equals("subtraction")) {
                  result = startNum - endNum;
              } else if (arithmeticType.equals("multiplication")) {
                  result = startNum * endNum;
              } else {
                  result = startNum / endNum;
              }
              System.out.println("====================>" + result);
              return result;
          }
      }

      调用地址:http://localhost:8080/testController/arithmetic02?arithmeticType=addition&startNum=5&endNum=5

    • 重构:下面使用策略设计模式,对业务进行重构

    创建一个接口类:BaseHandler

    1. package com.example.designpattern.celuemoshi.firstvesion;
      
      /**
       * @author shkstart
       * @create 2021-07-11 22:23
       */
      public interface BaseHandler {
      //    public  double result = 0.0;
      
          public double arithmetic(int startNum, int endNum);
      }

    创建加减乘法四种业务对应的接口实现类

    • 加法实现类 
    1. package com.example.designpattern.celuemoshi.firstvesion;
      
      import org.springframework.stereotype.Service;
      
      /**
       * @author shkstart
       * @create 2021-07-11 22:25
       */
      @Service("addition")
      public class AdditionHandler implements BaseHandler{
      
          @Override
          public double arithmetic(int startNum, int endNum) {
             return startNum + endNum;
      
          }
      }
    •  减法实现类
    1. package com.example.designpattern.celuemoshi.firstvesion;
      
      import org.springframework.stereotype.Service;
      
      /**
       * @author shkstart
       * @create 2021-07-11 22:30
       */
      @Service("subtraction")
      public class SubtractionHandler implements  BaseHandler {
          @Override
          public double arithmetic(int startNum, int endNum) {
              return  startNum - endNum;
          }
      }
    • 乘法实现类 
    1. package com.example.designpattern.celuemoshi.firstvesion;
      
      import org.springframework.stereotype.Service;
      
      /**
       * @author shkstart
       * @create 2021-07-11 22:31
       */
      @Service("multiplication")
      public class MultiplicationHandler implements  BaseHandler{
          @Override
          public double arithmetic(int startNum, int endNum) {
              return startNum * endNum;
          }
      }
    • 除法实现类 
    1. package com.example.designpattern.celuemoshi.firstvesion;
      
      import org.springframework.stereotype.Service;
      
      /**
       * @author shkstart
       * @create 2021-07-11 22:32
       */
      @Service("division")
      public class DivisionHandler implements BaseHandler {
          @Override
          public double arithmetic(int startNum, int endNum) {
              return startNum / endNum;
          }
      }

    Controller类代码,使用@Autowired将BaseHandler注入

    1. package com.example.designpattern.celuemoshi.firstvesion;
      
      import javafx.application.Application;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;
      
      import java.util.Map;
      
      /**
       * @author shkstart
       * @create 2021-07-11 22:16
       */
      @RestController
      @RequestMapping("/testController2")
      public class TestController2 {
          @Autowired
          private Map<String,BaseHandler> handlerMap;
      
      
          @RequestMapping("/arithmetic")
          public double arithmetic02(String arithmeticType, int startNum, int endNum) {//arithmetic算术
              BaseHandler baseHandler = handlerMap.get(arithmeticType);
              double arithmetic = baseHandler.arithmetic(startNum, endNum);
              return arithmetic;
          }
      }

      调用地址:http://localhost:8080/testController2/arithmetic?arithmeticType=addition&startNum=5&endNum=5

    @component注解会把普通pojo实例化到spring容器中,相当于配置文件中的<bean id="",class=""/>,启动项目时加载到handlerMap中,下面通过debug调试查看

     

    思考如果这种方法不可行,我们可以采用工厂模式来完成

     定义枚举

    package com.example.designpattern.celuemoshi.secondvesion.enmu;
    
    
    
    /**
     * @author shkstart
     * @create 2021-07-11 23:12
     */
    public enum  ArithmeticEnum {
        addition("addition","com.example.designpattern.celuemoshi.firstvesion.AdditionHandler"),
        division("division","com.example.designpattern.celuemoshi.firstvesion.DivisionHandler"),
        multiplication("multiplication","com.example.designpattern.celuemoshi.firstvesion.MultiplicationHandler"),
        subtraction("subtraction","com.example.designpattern.celuemoshi.firstvesion.SubtractionHandler");
        String type;
        String value;
    
        private ArithmeticEnum(String type, String value) {
            this.type = type;
            this.value = value;
        }
    
    
    
        public String getType() {
            return type;
        }
    
        public void setType(String type) {
            this.type = type;
        }
    
        public java.lang.String getValue() {
            return value;
        }
    
        public void setValue(String value) {
            this.value = value;
        }
    
        public static ArithmeticEnum getObj(java.lang.String type){
            for (ArithmeticEnum e : ArithmeticEnum.values()) {
                if(type.equals(e.getType())){
                    return e;
                }
            }
            return null;
        }
    }

    定义工厂类

    package com.example.designpattern.celuemoshi.secondvesion;
    
    import com.example.designpattern.celuemoshi.firstvesion.BaseHandler;
    import com.example.designpattern.celuemoshi.secondvesion.enmu.ArithmeticEnum;
    
    
    /**
     * @author shkstart
     * @create 2021-07-11 23:08
     * 使用工厂模式创建对象
     */
    public class StrategyFacade {
    
        public BaseHandler getStrategyType(String arithmeticType) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
            ArithmeticEnum obj = ArithmeticEnum.getObj(arithmeticType);
    
            BaseHandler o = (BaseHandler) Class.forName(obj.getValue()).newInstance();
            return o;
        }
    }

    定义controller

    package com.example.designpattern.celuemoshi.secondvesion;
    
    import com.example.designpattern.celuemoshi.firstvesion.BaseHandler;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.Map;
    
    /**
     * @author shkstart
     * @create 2021-07-11 22:16
     */
    @RestController
    @RequestMapping("/testController3")
    public class TestController3 {
    
    
    
        @RequestMapping("/arithmetic")
        public double arithmetic02(String arithmeticType, int startNum, int endNum) throws IllegalAccessException, InstantiationException, ClassNotFoundException {//arithmetic算术
            StrategyFacade strategyFacade = new StrategyFacade();
            BaseHandler strategyType = strategyFacade.getStrategyType(arithmeticType);
            double arithmetic = strategyType.arithmetic(startNum, endNum);
            return arithmetic;
        }
    }

    调用地址:http://localhost:8080/testController3/arithmetic?arithmeticType=addition&startNum=5&endNum=5

    • 总结

    1. @component将所有的bean实例化到Spring中,是一个map格式,@component注解的属性值就是map的key。
    2. 使用设计模式完全避免了大量的if...else,代码看起来简洁,便于后期扩展和维护。
    3. 后期新增业务只需关注自己的业务点,不需要新增逻辑判断。
    4. 缺点就是需要创建很多的实现类。
  • 相关阅读:
    【资源共享】JNI 课题
    Firefly自动售货机解决方案
    【资源共享】Android开发技巧整理
    【资源共享】《Rockchip IO-Domain 开发指南 V1.0》
    【人脸识别+硬件】Firefly推出可商业化的人脸识别方案
    【技术案例】双目摄像头数据采集
    windows环境常用网络命令测试和分析(51cto实验01~02)
    利用三层交换机实现VLAN间路由配置
    c++11
    归并排序
  • 原文地址:https://www.cnblogs.com/cj8357475/p/15000194.html
Copyright © 2020-2023  润新知