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

          共 5323字,需瀏覽 11分鐘

           ·

          2022-02-12 20:07

          上一篇:大年初一連夜帶娃改bug:CTO把代碼寫成這鬼樣子,被害慘了!

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

          details/109197926

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

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

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

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

          第一個能想到的思路就是if-else或者switch case:
          switch(resourceType){
           case "紅包"
            查詢紅包的派發(fā)方式 
            break;
           case "購物券"
            查詢購物券的派發(fā)方式
            break;
           case "QQ會員" :
            break;
           case "外賣會員" :
            break;
           ......
           default : logger.info("查找不到該優(yōu)惠券類型resourceType以及對應的派發(fā)方式");
            break;
          }
          如果要這么寫的話, 一個方法的代碼可就太長了,影響了可讀性。(別看著上面case里面只有一句話,但實際情況是有很多行的)
          而且由于 整個 if-else的代碼有很多行,也不方便修改,可維護性低。

          策略模式

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

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

          策略模式在業(yè)務邏輯分派的時候還是if-else,只是說比第一種思路的if-else 更好維護一點。微信搜索公眾號:互聯(lián)網(wǎng)架構(gòu)師,回復“2T”,獲取更多精品學習資料
          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以及對應的派發(fā)方式");
            break;
          但缺點也明顯:


          Map+函數(shù)式接口

          用上了Java8的新特性lambda表達式
          這樣子寫的好處是非常直觀,能直接看到判斷條件對應的業(yè)務邏輯

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

          上代碼:

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

              /**
               *  初始化業(yè)務分派邏輯,代替了if-else部分
               *  key: 優(yōu)惠券類型
               *  value: lambda表達式,最終會獲得該優(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<String,String> result=getGrantTypeMap.get(resourceType);
                  if(result!=null){
                   //傳入resourceId 執(zhí)行這段表達式獲得String型的grantType
                      return result.apply(resourceId);
                  }
                  return "查詢不到該優(yōu)惠券的發(fā)放方式";
              }
          }

          如果單個 if 語句塊的業(yè)務邏輯有很多行的話,我們可以把這些 業(yè)務操作抽出來,寫成一個單獨的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表達式才行啊,他不會讓他自己百度去

          最后捋一捋本文講了什么

          策略模式通過接口、實現(xiàn)類、邏輯分派來完成,把 if語句塊的邏輯抽出來寫成一個類,更好維護。
          Map+函數(shù)式接口通過Map.get(key)來代替 if-else的業(yè)務分派,能夠避免策略模式帶來的類增多、難以俯視整個業(yè)務邏輯的問題。

          相關閱讀:2T架構(gòu)師學習資料干貨分享


          1、2T架構(gòu)師學習資料干貨分享

          2、985副教授工資曝光

          3、心態(tài)崩了!稅前2萬4,到手1萬4,年終獎扣稅方式1月1日起施行~

          4、雷軍做程序員時寫的博客,很強大!

          5、人臉識別的時候,一定要穿上衣服?。?/a>

          6、清華大學:2021 元宇宙研究報告!

          7、績效被打3.25B,員工將支付寶告上了法院,判了

          瀏覽 48
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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>
                  色综合网址 | 成人污污污| 九九久久精品 | 日批后入试势动态视频免费看 | 黄色免费国产 |