Map+函数式接口如何完美的解决if-else问题?

需求
最近写了一个服务:根据优惠券的类型resourcetype和编码resourceid来 查询 发放方式granttype和领取规则
实现方式:
根据优惠券类型resourcetype -> 确定查询哪个数据表
根据编码resourceid -> 到对应的数据表里边查询优惠券的派发方式granttype和领取规则
优惠券有多种类型,分别对应了不同的数据库表:
红包 —— 红包发放规则表
购物券 —— 购物券表
qq会员
外卖会员
实际的优惠券远不止这些,这个需求是要我们写一个业务分派的逻辑
第一个能想到的思路就是if-else或者switch case:
switch(resourcetype){ case 红包:   查询红包的派发方式   break; case 购物券:   查询购物券的派发方式  break; case qq会员 :  break; case 外卖会员 :  break; ...... default : logger.info(查找不到该优惠券类型resourcetype以及对应的派发方式);  break;}  
如果要这么写的话, 一个方法的代码可就太长了,影响了可读性。(别看着上面case里面只有一句话,但实际情况是有很多行的)
而且由于 整个 if-else的代码有很多行,也不方便修改,可维护性低。
策略模式
策略模式是把 if语句里面的逻辑抽出来写成一个类,如果要修改某个逻辑的话,仅修改一个具体的实现类的逻辑即可,可维护性会好不少。
以下是策略模式的具体结构
策略模式在业务逻辑分派的时候还是if-else,只是说比第一种思路的if-else 更好维护一点。
switch(resourcetype){ case 红包:   string granttype=new context(new redpaper()).contextinterface();  break; case 购物券:   string granttype=new context(new shopping()).contextinterface();  break;  ...... default : logger.info(查找不到该优惠券类型resourcetype以及对应的派发方式);  break;  
但缺点也明显:
如果 if-else的判断情况很多,那么对应的具体策略实现类也会很多,上边的具体的策略实现类还只是2个,查询红包发放方式写在类redpaper里边,购物券写在另一个类shopping里边;那资源类型多个qq会员和外卖会员,不就得再多写两个类?有点麻烦了
没法俯视整个分派的业务逻辑
map+函数式接口
用上了java8的新特性lambda表达式
判断条件放在key中
对应的业务逻辑放在value中
这样子写的好处是非常直观,能直接看到判断条件对应的业务逻辑
需求:根据优惠券(资源)类型resourcetype和编码resourceid查询派发方式granttype
上代码:
@servicepublic class querygranttypeservice {     @autowired    private granttypeserive granttypeserive;    private map granttypemap=new hashmap();    /**     *  初始化业务分派逻辑,代替了if-else部分     *  key: 优惠券类型     *  value: lambda表达式,最终会获得该优惠券的发放方式     */    @postconstruct    public void dispatcherinit(){        granttypemap.put(红包,resourceid->granttypeserive.redpaper(resourceid));        granttypemap.put(购物券,resourceid->granttypeserive.shopping(resourceid));        granttypemap.put(qq会员,resourceid->granttypeserive.qqvip(resourceid));    }     public string getresult(string resourcetype){        //controller根据 优惠券类型resourcetype、编码resourceid 去查询 发放方式granttype        function result=getgranttypemap.get(resourcetype);        if(result!=null){         //传入resourceid 执行这段表达式获得string型的granttype            return result.apply(resourceid);        }        return 查询不到该优惠券的发放方式;    }}  
如果单个 if 语句块的业务逻辑有很多行的话,我们可以把这些 业务操作抽出来,写成一个单独的service,即:
//具体的逻辑操作@servicepublic class granttypeserive {    public string redpaper(string resourceid){        //红包的发放方式        return 每周末9点发放;    }    public string shopping(string resourceid){        //购物券的发放方式        return 每周三9点发放;    }    public string qqvip(string resourceid){        //qq会员的发放方式        return 每周一0点开始秒杀;    }}  
入参string resourceid是用来查数据库的,这里简化了,传参之后不做处理。
用http调用的结果:
@restcontrollerpublic class granttypecontroller {    @autowired    private querygranttypeservice querygranttypeservice;    @postmapping(/granttype)    public string test(string resourcename){        return querygranttypeservice.getresult(resourcename);    }}  
用map+函数式接口也有弊端:
你的队友得会lambda表达式才行啊,他不会让他自己百度去
最后捋一捋本文讲了什么
策略模式通过接口、实现类、逻辑分派来完成,把 if语句块的逻辑抽出来写成一个类,更好维护。
map+函数式接口通过map.get(key)来代替 if-else的业务分派,能够避免策略模式带来的类增多、难以俯视整个业务逻辑的问题。


基于NVDK C6416处理平台实现H.264的优化解码算法
电线连接器和接线端子的区别
测量仪器的常见类型有哪些
LMDGridPack是一组组件
硅光电池参数_硅光电池特性
Map+函数式接口如何完美的解决if-else问题?
iphone8发布会时间确定,库克亲自曝光iPhone8尺寸和最终售价曝光,十周年力作值得期待!
无线测温系统设计方案
三菱FX系列PLC的三大通讯方式
如何在Processing中制作一个程序
诺基亚手机业务为何拖累富士康,诺基亚手机的攻势还能延续么
ITSM中的AI优势,更容易,更有效吗
为什么无人驾驶到现在还没有来到
华为开发者联盟怎么样_华为开发者联盟为开发者提供最优服务
负离子浓度检测仪常见故障如何解决
常见硬件原理图“英文缩写”大全
7000 All Programmable SoC加速可信系统开发
机器学习举一反三
如何解决服务器的散热问题
ADI:双端口双极性电源电路及功能描述