<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ù)式接口就搞定了...

          共 3442字,需瀏覽 7分鐘

           ·

          2022-01-29 02:24

          關(guān)注Java核心技術(shù),推送更多 Java 干貨!539a3b795e30b76ccb01106599d1b4e5.webp

          來源:https://blog.csdn.net/qq_44384533/article/details/109197926

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

          文章目錄

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

          需求

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

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

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

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

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

          switch(resourceType){
          ?case?"紅包":?
          ??查詢紅包的派發(fā)方式?
          ??break;
          ?case?"購物券":?
          ??查詢購物券的派發(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語句里面的邏輯抽出來寫成一個(gè)類,如果要修改某個(gè)邏輯的話,僅修改一個(gè)具體的實(shí)現(xiàn)類的邏輯即可,可維護(hù)性會(huì)好不少。23 種設(shè)計(jì)模式實(shí)戰(zhàn)(很全)分享給你。

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

          8c6bcd48111c82cdecd6470231632fb7.webp

          策略模式在業(yè)務(wù)邏輯分派的時(shí)候還是if-else,只是說比第一種思路的if-else 更好維護(hù)一點(diǎn)。

          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以及對(duì)應(yīng)的派發(fā)方式");
          ??break;

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

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

          Map+函數(shù)式接口

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

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

          關(guān)注Java核心技術(shù),推送更多 Java 干貨!539a3b795e30b76ccb01106599d1b4e5.webp

          這樣子寫的好處是非常直觀,能直接看到判斷條件對(duì)應(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á)式,最終會(huì)獲得該優(yōu)惠券的發(fā)放方式
          ?????*/
          ????@PostConstruct
          ????public?void?dispatcherInit(){
          ????????grantTypeMap.put("紅包",resourceId->grantTypeSerive.redPaper(resourceId));
          ????????grantTypeMap.put("購物券",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?result=getGrantTypeMap.get(resourceType);
          ????????if(result!=null){
          ?????????//傳入resourceId?執(zhí)行這段表達(dá)式獲得String型的grantType
          ????????????return?result.apply(resourceId);
          ????????}
          ????????return?"查詢不到該優(yōu)惠券的發(fā)放方式";
          ????}
          }

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

          //具體的邏輯操作

          @Service
          public?class?GrantTypeSerive?{

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

          入?yún)tring resourceId是用來查數(shù)據(jù)庫的,這里簡(jiǎn)化了,傳參之后不做處理。23 種設(shè)計(jì)模式實(shí)戰(zhàn)(很全)分享給你。

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

          @RestController
          public?class?GrantTypeController?{

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

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

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

          最后捋一捋本文講了什么

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

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

          最近好文分享


          1. 一個(gè)由 “YYYY-MM-dd” 引發(fā)的慘案 !

          2. Java 中的 clone( ) 和 new,哪個(gè)效率更高?

          3. 提高 Java 效率的 35 個(gè)小技巧!

          4. Java 日志記錄最佳實(shí)踐,寫得太好了吧!

          5. 代碼寫的垃圾?這 3 個(gè)插件你值得擁有!

          更多請(qǐng)關(guān)注???Java核心技術(shù)

          一個(gè)分享Java核心技術(shù)干貨的公眾號(hào)

          點(diǎn)擊閱讀原文獲取免費(fèi)資料~
          瀏覽 49
          點(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>
                  国产在线第一页 | 国产精品嫩草AV城中村 | 欧美自拍视频 在线 | 亚洲性爱电影网站 | 夫妻自拍在线观看 |