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

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

3天內(nèi)不再提示

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

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

需求

最近寫了一個服務(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)惠券遠不止這些,這個需求是要我們寫一個業(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)

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

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

switch(resourceType){
case"紅包":
StringgrantType=newContext(newRedPaper()).ContextInterface();
break;
case"購物券":
StringgrantType=newContext(newShopping()).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表達式

判斷條件放在key中

對應(yīng)的業(yè)務(wù)邏輯放在value中

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

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

上代碼:

@Service
publicclassQueryGrantTypeService{

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

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

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

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

//具體的邏輯操作

@Service
publicclassGrantTypeSerive{

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

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

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

@RestController
publicclassGrantTypeController{

@Autowired
privateQueryGrantTypeServicequeryGrantTypeService;

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

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

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

最后捋一捋本文講了什么

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

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






審核編輯:劉清

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

    關(guān)注

    44

    文章

    3556

    瀏覽量

    133832
  • 數(shù)據(jù)庫
    +關(guān)注

    關(guān)注

    7

    文章

    3739

    瀏覽量

    64179

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

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

收藏 人收藏

    評論

    相關(guān)推薦

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

    在C語言中,有三種條件判斷結(jié)構(gòu):if語句、if-else語句和switch語句。
    發(fā)表于 08-18 16:36 ?9126次閱讀
    C語言中if語句、<b class='flag-5'>if-else</b>語句和switch語句詳解

    煉獄傳奇-if_else與case之戰(zhàn)

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

    Proteus之if-else語句的應(yīng)用

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

    FPGA學習系列:if-else與case

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

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

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

    不會有人不知道怎么優(yōu)雅的替換if-else語句吧

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

    像Arduino里的MAP函數(shù),應(yīng)用在STM32單片機上。

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

    關(guān)于Python中的“for-else”功能

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

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

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

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

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

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

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

    動態(tài)函數(shù)接口的調(diào)用原理

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

    函數(shù)接口的應(yīng)用知識點

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

    什么是函數(shù)接口

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

    Verilog代碼:if-else和case的電路結(jié)構(gòu)和區(qū)別

    每個if-else就是一個2選1mux器。當信號有明顯優(yōu)先級時,首先要考慮if-else,但是if嵌套過多也會導致速度變慢;if語句結(jié)構(gòu)較慢,但占用面積小。 嵌套的if語句如果使用不當,就會
    的頭像 發(fā)表于 11-29 15:10 ?2480次閱讀