• 策略模式-实战


    背景

    不同类型的业务表单,都有一个获取详情的方法。但是不同的业务表单,结构都不一样。

    实现一:if-else

    通过对表单类型做if-else判断,具体表单按照各自的类型获取详情。

            int businessType = 前端传过来表单类型;
            if(businessType==1){
                //组装表单1的详情信息,并返回
            }else if (businessType=2){
                //组装表单2的详情信息,并返回
            }else if (businessType=3){
                //组装表单3的详情信息,并返回
            }
            ..很多的if-else..
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    实现二:switch

    通过switch-case实现,具体表单按照各自的类型获取详情。

    switch (businessType) {
                case 1:
                    //组装表单1的详情信息,并返回
                    break;
                case 2:
                    //组装表单2的详情信息,并返回
                    break;
                case 3:
                    //组装表单3的详情信息,并返回
                    break;
                //......
                default:
                    break;
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    实现三:策略模式

    定义

    策略模式(Strategy Pattern)属于对象的行为模式。
    用意:针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。
    策略模式使得算法可以在不影响到客户端的情况下发生变化。
    其主要目的是通过定义相似的算法,替换if else 语句写法,并且可以随时相互替换。

    组成

    策略模式主要由3个角色组成:
    –环境角色(Context):持有一个策略类的引用,提供给客户端使用;
    –抽象策略角色(Strategy):这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口;
    –具体策略角色(ConcreteStrategy):包装了相关的算法或行为。

    优点

    扩展性好,可以在不修改对象结构的情况下,为新的算法进行添加新的类进行实现;
    灵活性好,可以对算法进行自由切换;

    缺点

    使用策略类变多,会增加系统的复杂度。;
    客户端必须知道所有的策略类才能进行调用;

    使用场景

    如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为;
    一个系统需要动态地在几种算法中选择一种;
    如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现;

    代码实现

    Controller

    reqData中的businessType,就是业务表单类型,值为1,2,3,4,5,6…

    @RestController
    public class InfoController {
    
        @Resource
        private Map<String, StrategyInfoService> strategyInfoService;
        // StrategyInfoService就是Strategy
        /**
         * 表单详情
         * @param reqData
         * @return
         */
        @PostMapping(value = "/getDetail")
        public Response<DetailVo> getDetail(@RequestBody ReqData reqData) {
            return Response.buildSuccess(this.strategyInfoService.get(String.valueOf(reqData.getBusinessType())).getDetailInfo(reqData));
            //get(String.valueOf(reqData.getBusinessType()),就已经用到了环境角色(Context)
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    抽象策略角色(Strategy)——StrategyInfoService

    public interface StrategyInfoService{
    
        /**
         * 获取表单详情的代理类
         * @param reqData
         * @return
         */
        DetailVo getDetailInfo(ReqData reqData);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    具体策略角色(ConcreteStrategy)

    @Service("1")
    public class BusinessOneFormInfoServiceImpl implements StrategyInfoService{
        
        @Override
        public DetailVo getDetailInfo(ReqData  reqData) {
            //获取表单类型1的详情,通过调用对应的service或者mapper或者其他方法
            return "表单类型1的详情";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    @Service("2")
    public class BusinessTwoFormInfoServiceImpl implements StrategyInfoService{
        
        @Override
        public DetailVo getDetailInfo(ReqData  reqData) {
            //获取表单类型2的详情,通过调用对应的service或者mapper或者其他方法
            return "表单类型2的详情";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    @Service("3")
    public class BusinessThreeFormInfoServiceImpl implements StrategyInfoService{
      
        @Override
        public DetailVo getDetailInfo(ReqData  reqData) {
            //获取表单类型3的详情,通过调用对应的service或者mapper或者其他方法
            return "表单类型3的详情";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    总结

    相比switch-case,策略模式用了更多的代码,创建更多的类。
    但是业务持续扩展的时候,只需要创建新的类,不会对controller和原来的代码冲突。

  • 相关阅读:
    行业下滑,海尔智家继续逆增双11全网第一
    [云原生k8s] k8s资源限制以及探针检查
    Hive调优
    大数据之Hadoop(一)
    持有NPDP和PMP证书的伙伴们有福了!深圳的同学看过来
    高速电路设计----第三章(2)LVDS信号详解
    vue3+vite+ts真实项目笔记
    01.oracle介绍
    骨传导耳机品牌排名前十,盘点最受欢迎的五款TOP级骨传导耳机
    JSD-2204-RESTful-Service-SpringMVC-Day06
  • 原文地址:https://blog.csdn.net/qq_25844803/article/details/127888161