<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          還在用策略模式解決 if-else?Map+函數(shù)式接口方法才是YYDS!

          共 3657字,需瀏覽 8分鐘

           ·

          2022-06-13 00:52

          程序員的成長(zhǎng)之路
          互聯(lián)網(wǎng)/程序員/技術(shù)/資料共享 
          關(guān)注


          閱讀本文大概需要 3.5 分鐘。

          來(lái)自:blog.csdn.net/qq_44384533/article/details/109197926

          本文介紹策略模式的具體應(yīng)用以及Map+函數(shù)式接口如何 “更完美” 的解決 if-else的問題。


          # 文章目錄


          • 需求
          • 策略模式
          • Map+函數(shù)式接口
          • 最后捋一捋本文講了什么

          # 需求


          最近寫了一個(gè)服務(wù):根據(jù)優(yōu)惠券的類型resourceType和編碼resourceId來(lái) 查詢 發(fā)放方式grantType和領(lǐng)取規(guī)則


          實(shí)現(xiàn)方式:


          • 根據(jù)優(yōu)惠券類型resourceType -> 確定查詢哪個(gè)數(shù)據(jù)表

          • 根據(jù)編碼resourceId -> 到對(duì)應(yīng)的數(shù)據(jù)表里邊查詢優(yōu)惠券的派發(fā)方式grantType和領(lǐng)取規(guī)則


          優(yōu)惠券有多種類型,分別對(duì)應(yīng)了不同的數(shù)據(jù)庫(kù)表:


          • 紅包 —— 紅包發(fā)放規(guī)則表

          • 購(gòu)物券 —— 購(gòu)物券表

          • QQ會(huì)員

          • 外賣會(huì)員


          實(shí)際的優(yōu)惠券遠(yuǎn)不止這些,這個(gè)需求是要我們寫一個(gè)業(yè)務(wù)分派的邏輯


          第一個(gè)能想到的思路就是if-else或者switch case:
          switch(resourceType){ case "紅包": 查詢紅包的派發(fā)方式 break; case "購(gòu)物券": 查詢購(gòu)物券的派發(fā)方式 break; case "QQ會(huì)員" : break; case "外賣會(huì)員" : break; ...... default : logger.info("查找不到該優(yōu)惠券類型resourceType以及對(duì)應(yīng)的派發(fā)方式"); break;}


          如果要這么寫的話, 一個(gè)方法的代碼可就太長(zhǎng)了,影響了可讀性。(別看著上面case里面只有一句話,但實(shí)際情況是有很多行的)


          而且由于 整個(gè) if-else的代碼有很多行,也不方便修改,可維護(hù)性低。


          # 策略模式


          策略模式是把 if語(yǔ)句里面的邏輯抽出來(lái)寫成一個(gè)類,如果要修改某個(gè)邏輯的話,僅修改一個(gè)具體的實(shí)現(xiàn)類的邏輯即可,可維護(hù)性會(huì)好不少。


          以下是策略模式的具體結(jié)構(gòu)


          策略模式在業(yè)務(wù)邏輯分派的時(shí)候還是if-else,只是說比第一種思路的if-else 更好維護(hù)一點(diǎn)。
          switch(resourceType){ case "紅包": String grantType=new Context(new RedPaper()).ContextInterface(); break; case "購(gòu)物券": String grantType=new Context(new Shopping()).ContextInterface(); break; ...... default : logger.info("查找不到該優(yōu)惠券類型resourceType以及對(duì)應(yīng)的派發(fā)方式"); break;

          但缺點(diǎn)也明顯:

          • 如果 if-else的判斷情況很多,那么對(duì)應(yīng)的具體策略實(shí)現(xiàn)類也會(huì)很多,上邊的具體的策略實(shí)現(xiàn)類還只是2個(gè),查詢紅包發(fā)放方式寫在類RedPaper里邊,購(gòu)物券寫在另一個(gè)類Shopping里邊;那資源類型多個(gè)QQ會(huì)員和外賣會(huì)員,不就得再多寫兩個(gè)類?有點(diǎn)麻煩了

          • 沒法俯視整個(gè)分派的業(yè)務(wù)邏輯

          # Map+函數(shù)式接口


          用上了Java8的新特性lambda表達(dá)式

          • 判斷條件放在key中
          • 對(duì)應(yīng)的業(yè)務(wù)邏輯放在value中

          這樣子寫的好處是非常直觀,能直接看到判斷條件對(duì)應(yīng)的業(yè)務(wù)邏輯
          需求:根據(jù)優(yōu)惠券(資源)類型resourceType和編碼resourceId查詢派發(fā)方式grantType

          上代碼:
          @Servicepublic class QueryGrantTypeService { @Autowired private GrantTypeSerive grantTypeSerive; private Map<String, Function<String,String>> grantTypeMap=new HashMap<>();
          /** * 初始化業(yè)務(wù)分派邏輯,代替了if-else部分 * key: 優(yōu)惠券類型 * value: lambda表達(dá)式,最終會(huì)獲得該優(yōu)惠券的發(fā)放方式 */ @PostConstruct public void dispatcherInit(){ grantTypeMap.put("紅包",resourceId->grantTypeSerive.redPaper(resourceId)); grantTypeMap.put("購(gòu)物券",resourceId->grantTypeSerive.shopping(resourceId)); grantTypeMap.put("qq會(huì)員",resourceId->grantTypeSerive.QQVip(resourceId)); } public String getResult(String resourceType){ //Controller根據(jù) 優(yōu)惠券類型resourceType、編碼resourceId 去查詢 發(fā)放方式grantType Function<String,String> result=getGrantTypeMap.get(resourceType); if(result!=null){ //傳入resourceId 執(zhí)行這段表達(dá)式獲得String型的grantType return result.apply(resourceId); } return "查詢不到該優(yōu)惠券的發(fā)放方式"; }}

          如果單個(gè) if 語(yǔ)句塊的業(yè)務(wù)邏輯有很多行的話,我們可以把這些 業(yè)務(wù)操作抽出來(lái),寫成一個(gè)單獨(dú)的Service,即:
          //具體的邏輯操作
          @Servicepublic class GrantTypeSerive {
          public String redPaper(String resourceId){ //紅包的發(fā)放方式 return "每周末9點(diǎn)發(fā)放"; } public String shopping(String resourceId){ //購(gòu)物券的發(fā)放方式 return "每周三9點(diǎn)發(fā)放"; } public String QQVip(String resourceId){ //qq會(huì)員的發(fā)放方式 return "每周一0點(diǎn)開始秒殺"; }}

          入?yún)tring resourceId是用來(lái)查數(shù)據(jù)庫(kù)的,這里簡(jiǎn)化了,傳參之后不做處理。

          用http調(diào)用的結(jié)果:
          @RestControllerpublic class GrantTypeController {
          @Autowired private QueryGrantTypeService queryGrantTypeService;
          @PostMapping("/grantType") public String test(String resourceName){ return queryGrantTypeService.getResult(resourceName); }}

          用Map+函數(shù)式接口也有弊端:

          • 你的隊(duì)友得會(huì)lambda表達(dá)式才行啊,他不會(huì)讓他自己百度去


          # 最后捋一捋本文講了什么


          策略模式通過接口、實(shí)現(xiàn)類、邏輯分派來(lái)完成,把 if語(yǔ)句塊的邏輯抽出來(lái)寫成一個(gè)類,更好維護(hù)。

          Map+函數(shù)式接口通過Map.get(key)來(lái)代替 if-else的業(yè)務(wù)分派,能夠避免策略模式帶來(lái)的類增多、難以俯視整個(gè)業(yè)務(wù)邏輯的問題。

          <END>

          推薦閱讀:

          SpringBoot 實(shí)現(xiàn) Office 各種格式在線預(yù)覽(詳細(xì)教程,包教包會(huì))

          執(zhí)行count(1)、count(*) 與 count(列名) 到底有什么區(qū)別?

          互聯(lián)網(wǎng)初中高級(jí)大廠面試題(9個(gè)G)

          內(nèi)容包含Java基礎(chǔ)、JavaWeb、MySQL性能優(yōu)化、JVM、鎖、百萬(wàn)并發(fā)、消息隊(duì)列、高性能緩存、反射、Spring全家桶原理、微服務(wù)、Zookeeper......等技術(shù)棧!

          ?戳閱讀原文領(lǐng)?。?/span>                                  朕已閱 

          瀏覽 17
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲AAA区高清 | 欧美啪啪视频 | 九九热在线精品视频 | 操极品美女 | 在线操屄观看 |