当前位置: 首页 > 后端技术 > Java

还在用策略模式解决if-else?地图+功能界面就搞定了,..

时间:2023-04-02 00:20:19 Java

来源:https://blog.csdn.net/qq_4438...本文介绍了策略模式的具体应用以及Map+函数式接口如何“更完美”解决if-else问题。文章目录需求攻略模式图+功能接口最后我们来看看这篇文章的需求是什么。最近写了一个服务:根据优惠券类型resourceType和coderesourceId查询发放方式grantType和领取规则。实现方法:根据优惠券类型resourceType->根据代码resourceId确定查询哪个数据表->到对应数据表查询优惠券发放方式grantType和领取规则优惠券有很多种,分别对应不同的数据库表:红包-红包发放规则表优惠券——购物券表QQ会员外卖会员实际的优惠券远不止这些。这个需求需要我们写一个业务分配的逻辑。第一个想到的思路是if-else或者switchcase:switch(resourceType){case"红包":查询红包break的发放方式;case“购物券”:查询购物券断点的分配方式;case"QQ会员":break;case“外卖会员”:break;......default:logger.info("找不到优惠券类型的resourceType和对应的分发方式");break;}如果要这样写,一个方法的代码会太长,影响可读性。(别看上面的案例只有一句话,实际情况是很多行)而且因为整个if-else代码行很多,不方便修改,可维护性低。策略模式策略模式就是将if语句中的逻辑抽取出来写成一个类。如果要修改某个逻辑,只需要修改具体实现类的逻辑,可维护性会好很多。下面是策略模式的具体结构。策略模式在业务逻辑赋值的时候还是if-else,但是比第一个if-else更好维护。switch(resourceType){case"红包":StringgrantType=newContext(newRedPaper()).ContextInterface();休息;case"shoppingvoucher":StringgrantType=newContext(newShopping()).ContextInterface();休息;......default:logger.info("找不到优惠券类型resourceType和对应的分发方式");休息;但是缺点也很明显:如果if-else判断比较多,那么对应的具体策略实现类也比较多。上面只有两个具体的策略实现类。查询红包发放方法写在RedPaper类中,购物券写在另一个类Shopping中;资源类型为多个QQ会员和外卖会员,你不是还要写两个类吗?有点麻烦,又不能忽略dispatch的整个业务逻辑。Map+functional接口使用了Java8的新特性lambda表达式。判断条件放在key中,相应的业务逻辑放在value中。这样写的好处是非常直观,可以直接看到判断条件对应的业务逻辑需求:根据优惠券(资源)类型resourceType和代码resourceId代码查询分发方式grantType:@ServicepublicclassQueryGrantTypeService{@Autowired私有GrantTypeServivegrantTypeServive;privateMap>grantTypeMap=newHashMap<>();/***初始化业务分配逻辑,替换if-else部分*key:Coupontype*value:lambdaexpression,最终得到优惠券发放方式*/@PostConstructpublicvoiddispatcherInit(){grantTypeMap.put("红包",resourceId->grantTypeSerive.redPaper(resourceId));grantTypeMap.put("购物券",resourceId->grantTypeSerive.shopping(resourceId));grantTypeMap.put("qq会员",resourceId->grantTypeSerive.QQVip(resourceId));}publicStringgetResult(StringresourceType){//Controller根据优惠券类型resourceType和coderesourceId查询grantType。functionresult=getGrantTypeMap.get(resourceType);if(result!=null){//传入resourceId,执行这个表达式得到一个String类型的grantTypereturnresult.apply(resourceId);}return"优惠券发放方式无法查询";}}如果单个if语句块如果业务逻辑很多行,我们可以把这些业务操作抽取出来写成一个单独的Service,即://具体逻辑操作@ServicepublicclassGrantTypeSerive{publicStringredPaper(StringresourceId){//如何发红包return"每周末9点派发";}publicStringshopping(StringresourceId){//如何发放购物券return"每周三九点发放";}公共海峡ingQQVip(StringresourceId){//qq会员怎么发return"每周一0:00秒杀";}}输入参数StringresourceId用于查询数据库,这里简化。传递参数后,不会被http处理和调用@PostMapping("/grantType")publicStringtest(StringresourceName){returnqueryGrantTypeService.getResult(resourceName);}}使用Map+函数式接口也有缺点:你的Teammates必须会lambda表达式,他不会让他最后一次去百度。本文讲的是策略模式通过接口、实现类、逻辑赋值完成,将if语句块的逻辑抽取出来写成一个类,更好的维护。Map+功能接口使用Map.get(key)代替if-else业务赋值,可以避免策略模式带来的增加类,难以忽略整个业务逻辑的问题。近期热点文章推荐:1.1000+Java面试题及答案(2022最新版)2.厉害了!Java协程来了。..3.SpringBoot2.x教程,太全面了!4.20w程序员红包封面,快拿。..5.《Java开发手册(嵩山版)》最新发布,赶快下载吧!感觉不错,别忘了点赞+转发!