<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!

          共 3469字,需瀏覽 7分鐘

           ·

          2022-01-22 18:55

          來源:blog.csdn.net/qq_44384533/article/

          details/109197926

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

          文章目錄

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

          需求

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

          實現(xiàn)方式:
          • 根據(jù)優(yōu)惠券類型resourceType -> 確定查詢哪個數(shù)據(jù)表
          • 根據(jù)編碼resourceId -> 到對應(yīng)的數(shù)據(jù)表里邊查詢優(yōu)惠券的派發(fā)方式grantType和領(lǐng)取規(guī)則

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

          • 紅包 —— 紅包發(fā)放規(guī)則表
          • 購物券 —— 購物券表
          • QQ會員
          • 外賣會員

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

          第一個能想到的思路就是if-else或者switch case:

          switch(resourceType){
          ?case?"紅包":?
          ??查詢紅包的派發(fā)方式?
          ??break;
          ?case?"購物券":?
          ??查詢購物券的派發(fā)方式
          ??break;
          ?case?"QQ會員"?:
          ??break;
          ?case?"外賣會員"?:
          ??break;
          ?......
          ?default?:?logger.info("查找不到該優(yōu)惠券類型resourceType以及對應(yīng)的派發(fā)方式");
          ??break;
          }

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

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

          策略模式

          策略模式是把 if語句里面的邏輯抽出來寫成一個類,如果要修改某個邏輯的話,僅修改一個具體的實現(xiàn)類的邏輯即可,可維護性會好不少。

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

          策略模式在業(yè)務(wù)邏輯分派的時候還是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("查找不到該優(yōu)惠券類型resourceType以及對應(yīng)的派發(fā)方式");
          ??break;

          但缺點也明顯:

          • 如果 if-else的判斷情況很多,那么對應(yīng)的具體策略實現(xiàn)類也會很多,上邊的具體的策略實現(xiàn)類還只是2個,查詢紅包發(fā)放方式寫在類RedPaper里邊,購物券寫在另一個類Shopping里邊;那資源類型多個QQ會員和外賣會員,不就得再多寫兩個類?有點麻煩了
          • 沒法俯視整個分派的業(yè)務(wù)邏輯

          Map+函數(shù)式接口

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

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

          這樣子寫的好處是非常直觀,能直接看到判斷條件對應(yīng)的業(yè)務(wù)邏輯

          需求:根據(jù)優(yōu)惠券(資源)類型resourceType和編碼resourceId查詢派發(fā)方式grantType

          上代碼:

          @Service
          public?class?QueryGrantTypeService?{
          ?
          ????@Autowired
          ????private?GrantTypeSerive?grantTypeSerive;
          ????private?Map>?grantTypeMap=new?HashMap<>();

          ????/**
          ?????*??初始化業(yè)務(wù)分派邏輯,代替了if-else部分
          ?????*??key:?優(yōu)惠券類型
          ?????*??value:?lambda表達(dá)式,最終會獲得該優(yōu)惠券的發(fā)放方式
          ?????*/

          ????@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根據(jù)?優(yōu)惠券類型resourceType、編碼resourceId?去查詢?發(fā)放方式grantType
          ????????Function?result=getGrantTypeMap.get(resourceType);
          ????????if(result!=null){
          ?????????//傳入resourceId?執(zhí)行這段表達(dá)式獲得String型的grantType
          ????????????return?result.apply(resourceId);
          ????????}
          ????????return?"查詢不到該優(yōu)惠券的發(fā)放方式";
          ????}
          }

          如果單個 if 語句塊的業(yè)務(wù)邏輯有很多行的話,我們可以把這些 業(yè)務(wù)操作抽出來,寫成一個單獨的Service,即:

          //具體的邏輯操作

          @Service
          public?class?GrantTypeSerive?{

          ????public?String?redPaper(String?resourceId){
          ????????//紅包的發(fā)放方式
          ????????return?"每周末9點發(fā)放";
          ????}
          ????public?String?shopping(String?resourceId){
          ????????//購物券的發(fā)放方式
          ????????return?"每周三9點發(fā)放";
          ????}
          ????public?String?QQVip(String?resourceId){
          ????????//qq會員的發(fā)放方式
          ????????return?"每周一0點開始秒殺";
          ????}
          }

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

          用http調(diào)用的結(jié)果:

          @RestController
          public?class?GrantTypeController?{

          ????@Autowired
          ????private?QueryGrantTypeService?queryGrantTypeService;

          ????@PostMapping("/grantType")
          ????public?String?test(String?resourceName){
          ????????return?queryGrantTypeService.getResult(resourceName);
          ????}
          }

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

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

          最后捋一捋本文講了什么

          策略模式通過接口、實現(xiàn)類、邏輯分派來完成,把 if語句塊的邏輯抽出來寫成一個類,更好維護。

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

          程序汪資料鏈接

          程序汪接的7個私活都在這里,經(jīng)驗整理

          Java項目分享 ?最新整理全集,找項目不累啦 04版

          堪稱神級的Spring Boot手冊,從基礎(chǔ)入門到實戰(zhàn)進階

          臥槽!字節(jié)跳動《算法中文手冊》火了,完整版 PDF 開放下載!

          臥槽!阿里大佬總結(jié)的《圖解Java》火了,完整版PDF開放下載!

          字節(jié)跳動總結(jié)的設(shè)計模式 PDF 火了,完整版開放下載!

          歡迎添加程序汪個人微信 itwang008? 進粉絲群或圍觀朋友圈

          瀏覽 23
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  色大屌| 欧美日韩在线免费观看视频 | 午夜二性 | 99思思视频 | 性欧美大战久久久久久久免费观看 |