那曲檬骨新材料有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Map+函數式接口如何完美的解決if-else問題?

jf_ro2CN3Fa ? 來源:CSDN ? 2023-09-07 11:07 ? 次閱讀

需求

最近寫了一個服務:根據優惠券的類型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語句里面的邏輯抽出來寫成一個類,如果要修改某個邏輯的話,僅修改一個具體的實現類的邏輯即可,可維護性會好不少。

以下是策略模式的具體結構

9fe00f06-4d1e-11ee-a25d-92fbcf53809c.png

策略模式在業務邏輯分派的時候還是if-else,只是說比第一種思路的if-else 更好維護一點。

switch(resourceType){
case"紅包":
StringgrantType=newContext(newRedPaper()).ContextInterface();
break;
case"購物券":
StringgrantType=newContext(newShopping()).ContextInterface();
break;

......
default:logger.info("查找不到該優惠券類型resourceType以及對應的派發方式");
break;

但缺點也明顯:

如果 if-else的判斷情況很多,那么對應的具體策略實現類也會很多,上邊的具體的策略實現類還只是2個,查詢紅包發放方式寫在類RedPaper里邊,購物券寫在另一個類Shopping里邊;那資源類型多個QQ會員和外賣會員,不就得再多寫兩個類?有點麻煩了

沒法俯視整個分派的業務邏輯

Map+函數式接口

用上了Java8的新特性lambda表達式

判斷條件放在key中

對應的業務邏輯放在value中

這樣子寫的好處是非常直觀,能直接看到判斷條件對應的業務邏輯

需求:根據優惠券(資源)類型resourceType和編碼resourceId查詢派發方式grantType

上代碼:

@Service
publicclassQueryGrantTypeService{

@Autowired
privateGrantTypeSerivegrantTypeSerive;
privateMap>grantTypeMap=newHashMap<>();

/**
*初始化業務分派邏輯,代替了if-else部分
*key:優惠券類型
*value:lambda表達式,最終會獲得該優惠券的發放方式
*/
@PostConstruct
publicvoiddispatcherInit(){
grantTypeMap.put("紅包",resourceId->grantTypeSerive.redPaper(resourceId));
grantTypeMap.put("購物券",resourceId->grantTypeSerive.shopping(resourceId));
grantTypeMap.put("qq會員",resourceId->grantTypeSerive.QQVip(resourceId));
}

publicStringgetResult(StringresourceType){
//Controller根據優惠券類型resourceType、編碼resourceId去查詢發放方式grantType
Functionresult=getGrantTypeMap.get(resourceType);
if(result!=null){
//傳入resourceId執行這段表達式獲得String型的grantType
returnresult.apply(resourceId);
}
return"查詢不到該優惠券的發放方式";
}
}

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

//具體的邏輯操作

@Service
publicclassGrantTypeSerive{

publicStringredPaper(StringresourceId){
//紅包的發放方式
return"每周末9點發放";
}
publicStringshopping(StringresourceId){
//購物券的發放方式
return"每周三9點發放";
}
publicStringQQVip(StringresourceId){
//qq會員的發放方式
return"每周一0點開始秒殺";
}
}

入參String resourceId是用來查數據庫的,這里簡化了,傳參之后不做處理。

用http調用的結果:

@RestController
publicclassGrantTypeController{

@Autowired
privateQueryGrantTypeServicequeryGrantTypeService;

@PostMapping("/grantType")
publicStringtest(StringresourceName){
returnqueryGrantTypeService.getResult(resourceName);
}
}
a010c98e-4d1e-11ee-a25d-92fbcf53809c.png

用Map+函數式接口也有弊端:

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

最后捋一捋本文講了什么

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

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






審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 編碼器
    +關注

    關注

    45

    文章

    3667

    瀏覽量

    135237
  • 數據庫
    +關注

    關注

    7

    文章

    3846

    瀏覽量

    64685

原文標題:Map+函數式接口,“更完美” 的解決 if-else的問題

文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    C語言中if語句、if-else語句和switch語句詳解

    在C語言中,有三種條件判斷結構:if語句、if-else語句和switch語句。
    發表于 08-18 16:36 ?1.2w次閱讀
    C語言中if語句、<b class='flag-5'>if-else</b>語句和switch語句詳解

    煉獄傳奇-if_else與case之戰

    Verilog HDL語言中存在兩種分支語言:● if-else 條件分支語句● case 分支控制語句1. if-else條件分支語句if-else 條件分支語句的作用是根據指定的判斷條件是否滿足
    發表于 03-31 09:51

    Proteus之if-else語句的應用

    Proteus之if-else語句的應用,很好的Proteus資料,快來學習吧。
    發表于 04-18 14:49 ?0次下載

    FPGA學習系列:if-else與case

    設計背景:不管是在什么軟件和硬件語言,我們在我們的代碼中都或多或少的用到這兩條語句,if..else與case語句,今天我們將學習verilog中的這兩條語句,其實不管在什么語言中這兩個語句都是一樣
    的頭像 發表于 06-01 16:59 ?1.2w次閱讀
    FPGA學習系列:<b class='flag-5'>if-else</b>與case

    從入門到高級替換If-Else的5種方法示例

    本文并不肯定或者否定哪一種寫法,僅僅為大家提供一些其他的編碼思路或者一些值得借鑒的點子。 設計更好的軟件,替換 If-Else 的 5 種方法,從入門到高級示例 If-Else 通常是一個糟糕的選擇
    的頭像 發表于 02-20 16:27 ?6885次閱讀
    從入門到高級替換<b class='flag-5'>If-Else</b>的5種方法示例

    不會有人不知道怎么優雅的替換if-else語句吧

    來自:love1024.blog.csdn.net/article/details/104955363 場景日常開發,if-else語句寫的不少吧??當邏輯分支非常多的時候,if-else套了一層
    的頭像 發表于 07-28 15:46 ?1484次閱讀
    不會有人不知道怎么優雅的替換<b class='flag-5'>if-else</b>語句吧

    像Arduino里的MAP函數,應用在STM32單片機上。

    像Arduino里的MAP函數,應用在STM32單片機上。簡介:如果大家玩過Arduino,想必知道MAP();函數了,這是一個很好用的映射函數
    發表于 12-24 19:29 ?0次下載
    像Arduino里的<b class='flag-5'>MAP</b><b class='flag-5'>函數</b>,應用在STM32單片機上。

    關于Python中的“for-else”功能

    無論使用哪種編程語言,我們都會編寫“if-else”語句,但是“for-else”呢?
    發表于 09-26 14:44 ?570次閱讀

    解鎖新姿勢:干掉過多的if-else

    這點非常容易理解,就是說在業務邏輯里面,先把不符合條件的給先過濾掉,而不是層層嵌套if-else判斷
    的頭像 發表于 11-12 10:01 ?683次閱讀

    什么是SystemVerilog-決策語句-if-else語句?

    決策語句(Decision statements)允許程序塊的執行流程根據設計中信號的當前值分支到特定語句。SystemVerilog有兩個主要的決策語句:if…else語句和case語句,使用關鍵字case、case…inside,casex和casez。
    的頭像 發表于 02-09 14:15 ?1252次閱讀
    什么是SystemVerilog-決策語句-<b class='flag-5'>if-else</b>語句?

    如何通過策略模式簡化if-else

    相信大家日常開發中會經常寫各種分支判斷語句,比如 if-else ,當分支較多時,代碼看著會比較臃腫,那么如何優化呢? 1、什么是策略模式? Define a family
    的頭像 發表于 10-08 16:08 ?802次閱讀
    如何通過策略模式簡化<b class='flag-5'>if-else</b>

    動態函數接口的調用原理

    本篇將從編譯,執行層面為大家講解函數接口運行的機制,讓各位小伙伴更進一步加深對函數接口的理解
    的頭像 發表于 10-13 11:27 ?490次閱讀
    動態<b class='flag-5'>函數</b><b class='flag-5'>接口</b>的調用原理

    函數接口的應用知識點

    概述 函數接口將分為三個篇章來為大家介紹: (應用篇一)(1)函數接口的來源,(2)Lamb
    的頭像 發表于 10-13 11:32 ?681次閱讀
    <b class='flag-5'>函數</b><b class='flag-5'>式</b><b class='flag-5'>接口</b>的應用知識點

    什么是函數接口

    Lambda表達式,相信大家都耳有所聞,而且不少小伙伴在日常的工作中也在使用。但說到函數接口,可能有一些即使會使用Lambda表達式的小伙伴也會覺得陌生。今天,指北君就將帶領大家對Lambda
    的頭像 發表于 10-13 14:48 ?1593次閱讀
    什么是<b class='flag-5'>函數</b><b class='flag-5'>式</b><b class='flag-5'>接口</b>

    Verilog代碼:if-else和case的電路結構和區別

    每個if-else就是一個2選1mux器。當信號有明顯優先級時,首先要考慮if-else,但是if嵌套過多也會導致速度變慢;if語句結構較慢,但占用面積小。 嵌套的if語句如果使用不當,就會
    的頭像 發表于 11-29 15:10 ?3578次閱讀
    百家乐| 扎鲁特旗| 房产| 赌王百家乐官网的玩法技巧和规则 | 百家乐高手怎么下注| 百家乐送錢平臺| 现金网开户| 百家乐官网体育nba| 华硕百家乐官网的玩法技巧和规则 | 大发888娱乐城登录| 百家乐官网洗码方法| 百家乐官网玩法注意事项| 尊龙百家乐官网娱乐场开户注册| 线上百家乐代理| 大发娱乐场官方下载| 百家乐官网楼梯缆大全| BB百家乐大转轮| 威尼斯人娱乐城代理| 永年县| 三元玄空24山坐向开门| 威尼斯人娱乐城 色情| 澳门在线赌场| 中国百家乐官网技巧| 免佣百家乐赌场优势| 顶级赌场官方客户端下载| 百家乐官网api| 百家乐打鱼秘籍| 皇冠网888799| 24山吉凶视频| 九乐棋牌下载| 巴比伦百家乐官网的玩法技巧和规则 | 网上百家乐辅助软件| bet365娱乐城| 百家乐官网最新分析仪 | 金龍百家乐的玩法技巧和规则| 皇冠百家乐官网皇冠网| 百家乐9人桌布| 博彩百家乐在线| 百家乐官网真钱电玩| 棋牌百家乐怎么玩| 腾飞国际娱乐城|