詳解Java如何優(yōu)雅地書寫if-else
0. 引言
在日常開發(fā)中我們常常遇到有多個(gè)if else的情況,之間書寫顯得代碼冗余難看,對于追求更高質(zhì)量代碼的同學(xué),就會思考如何優(yōu)雅地處理這種代碼
下面我們來探討下幾種優(yōu)化if else的方法
1. switch
switch方法針對枚舉值處理有不錯的效果,比如針對不同的訂單狀態(tài)時(shí)要做不同的處理,因?yàn)闋顟B(tài)值有限,這時(shí)我們就可以直接使用switch來針對不同狀態(tài)做不同的處理:
原語句
public void before(Integer status) { if(status == 1){ System.out.println("訂單未接單"); }else if(status == 2){ System.out.println("訂單未發(fā)貨"); }else if(status == 3){ System.out.println("訂單未簽收"); }else{ System.out.println("訂單已簽收"); } }
switch
public void greater(Integer status) { switch (status){ case 1: System.out.println("訂單未接單"); break; case 2: System.out.println("訂單未發(fā)貨"); break; case 3: System.out.println("訂單未簽收"); break; default: System.out.println("訂單已簽收"); } }
總結(jié):
switch語句適用于判斷條件有限且不需要經(jīng)過復(fù)雜的計(jì)算,處理語句簡單的場景。如果我們的判斷條件需要經(jīng)過一系列復(fù)雜的計(jì)算才能得到,或者處理語句邏輯也比較復(fù)雜時(shí),我們就要考慮其他的處理方式了,畢竟在case中書寫一大堆處理語句并不算得讓人舒適的事情
2. 函數(shù)式接口
針對比較復(fù)雜的處理邏輯時(shí),我們偏向于將這些處理邏輯單獨(dú)抽離出來,而不是還放在一個(gè)方法里處理,增加整體的可讀性和解耦性,也是我們衍生出利用函數(shù)式接口來處理if else的模式
函數(shù)式接口map處理if else的要義,是將各個(gè)條件的復(fù)雜處理邏輯單獨(dú)抽取為一個(gè)函數(shù)式接口方法,通過統(tǒng)一的判斷條件來調(diào)用不同的方法,具體示例如下
@Component public class FunctionInterfaceStrategy { /** * key 方法參數(shù),多個(gè)參數(shù)可以自定義一個(gè)實(shí)體類處理 * value 方法返回值 */ private Map<Integer, Function<Object,Boolean>> operationMap; @PostConstruct private void init(){ operationMap = new HashMap<>(); operationMap.put(1,this::takeOrder); operationMap.put(2,this::sendOrder); operationMap.put(3,this::signOrder); operationMap.put(4,this::finishOrder); } public Boolean doOperation(Object params,Integer status){ return operationMap.get(status) == null || operationMap.get(status).apply(params); } private Boolean takeOrder(Object params){ // TODO 比較復(fù)雜的處理邏輯 System.out.println("訂單未接單"); return true; } private Boolean sendOrder(Object params){ // TODO 比較復(fù)雜的處理邏輯 System.out.println("訂單未發(fā)貨"); return true; } private Boolean signOrder(Object params){ // TODO 比較復(fù)雜的處理邏輯 System.out.println("訂單未簽收"); return true; } private Boolean finishOrder(Object params){ // TODO 比較復(fù)雜的處理邏輯 System.out.println("訂單已簽收"); return true; } }
調(diào)用時(shí)就不用再用if else區(qū)分了,直接傳入?yún)?shù)到function map中調(diào)用
@Autowired private FunctionInterfaceStrategy functionInterfaceStrategy; functionInterfaceStrategy.doOperation("參數(shù)",1);
當(dāng)然我們上述演示的是有參數(shù)有返回值的函數(shù)式接口,實(shí)際生產(chǎn)中我們可能還需要其他形式的函數(shù)式接口,我們將其單獨(dú)羅列出來,供大家參考使用
接口名稱 | 說明 | 調(diào)用方法 |
---|---|---|
Supplier | 無參數(shù),有返回值 | get |
Consumer | 有參數(shù),無返回值 | accept |
Runnable | 無參數(shù),無返回值 | run |
Function | 有參數(shù),有返回值 | apply |
3. 策略模式
上述的函數(shù)式接口的形式,實(shí)際上是針對方法進(jìn)行了分離,所有的實(shí)現(xiàn)方法還是放在了一個(gè)類里,即使你可以在FunctionInterfaceStrategy類中通過依賴注入的形式再次調(diào)用其他類的方法,但是這樣的模式,已經(jīng)趨近于我們要將的下一種方法,即使用策略模式來解決 if else
策略模式的形式適用于實(shí)現(xiàn)方法更加復(fù)雜的情況,需要將處理邏輯解耦的更加干凈的場景
1、首先我們需要創(chuàng)建一個(gè)接口類,用來規(guī)定我們后續(xù)的實(shí)現(xiàn)類的格式
public interface OrderStrategy { /** * 獲取實(shí)現(xiàn)類標(biāo)識 * @return */ Integer getType(); /** * 邏輯處理 * @param params * @return */ Boolean handler(Object params); }
2、其次針對每個(gè)判斷條件創(chuàng)建一個(gè)實(shí)現(xiàn)類
@Service public class SendOrderStrategy implements OrderStrategy{ @Override public Integer getType() { return 2; } @Override public Boolean handler(Object params) { // TODO 復(fù)雜的處理邏輯 System.out.println("訂單未發(fā)貨"); return true; } } @Service public class SignOrderStrategy implements OrderStrategy{ @Override public Integer getType() { return 3; } @Override public Boolean handler(Object params) { // TODO 復(fù)雜的處理邏輯 System.out.println("訂單未簽收"); return true; } } @Service public class TakeOrderStrategy implements OrderStrategy{ @Override public Integer getType() { return 1; } @Override public Boolean handler(Object params) { // TODO 復(fù)雜的處理邏輯 System.out.println("訂單未接單"); return true; } }
3、創(chuàng)建一個(gè)策略工廠類,承裝實(shí)現(xiàn)類
@Component @AllArgsConstructor public class OrderStrategyFactory { private final List<OrderStrategy> orderStrategyList; private static Map<Integer,OrderStrategy> strategyMap = new HashMap<>(); @PostConstruct private void init(){ for (OrderStrategy orderStrategy : orderStrategyList) { strategyMap.put(orderStrategy.getType(),orderStrategy); } } /** * 執(zhí)行方法 * @param status * @param params * @return */ public Boolean handler(Integer status,Object params){ return strategyMap.get(status).handler(params); } }
4、方法調(diào)用
@RestController @RequestMapping("ifelse") @AllArgsConstructor public class IfElseController { private final OrderStrategyFactory orderStrategyFactory; @GetMapping("strategy") public Boolean strategy(Integer status){ return orderStrategyFactory.handler(status,"1"); } }
總結(jié):
通過上述的代碼示例,大家其實(shí)可以發(fā)現(xiàn),函數(shù)式接口和策略模式有異曲同工之處,根本區(qū)別在于是否需要將實(shí)現(xiàn)方法單獨(dú)抽取為一個(gè)實(shí)現(xiàn)類。抽取的粒度越細(xì)也就說明解耦越強(qiáng)
使用策略模式,后續(xù)如果需要增加if else條件的話,只需要增加實(shí)現(xiàn)類即可,針對后續(xù)的處理更加方便
最終使用哪一個(gè)還需要根據(jù)具體的業(yè)務(wù)情況而定
4. 衛(wèi)語句
我們經(jīng)常需要在方法前處理各種參數(shù)嵌套判斷邏輯,如果不滿足條件就直接返回了,這種情況更加推薦使用衛(wèi)語句來處理
原語句
public void before(Integer status) { if(status != null) { if(status != 0){ if(status == 1){ System.out.println("訂單未接單"); } } } }
衛(wèi)語句
public void greater(Integer status) { if(status == null){ return; } if(status != 0){ return; } if(status == 1){ System.out.println("訂單未接單"); } }
到此這篇關(guān)于詳解Java如何優(yōu)雅地書寫if-else的文章就介紹到這了,更多相關(guān)Java if-else內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot+Redis使用AOP防止重復(fù)提交的實(shí)現(xiàn)
本文主要介紹了SpringBoot+Redis使用AOP防止重復(fù)提交的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07SpringMVC結(jié)合ajaxfileupload實(shí)現(xiàn)文件無刷新上傳代碼
本篇文章主要介紹了SpringMVC結(jié)合ajaxfileupload實(shí)現(xiàn)文件無刷新上傳,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-04-04SpringBoot整合rockerMQ消息隊(duì)列詳解
今天和大家一起深入生產(chǎn)級別消息中間件 - RocketMQ 的內(nèi)核實(shí)現(xiàn),來看看真正落地能支撐萬億級消息容量、低延遲的消息隊(duì)列到底是如何設(shè)計(jì)的。我會先介紹整體的架構(gòu)設(shè)計(jì),然后再深入各核心模塊的詳細(xì)設(shè)計(jì)、核心流程的剖析2022-07-07IntelliJ IDEA創(chuàng)建maven多模塊項(xiàng)目(圖文教程)
這篇文章主要介紹了IntelliJ IDEA創(chuàng)建maven多模塊項(xiàng)目(圖文教程),非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-09-09在ssm中使用ModelAndView跳轉(zhuǎn)頁面失效的解決
這篇文章主要介紹了在ssm中使用ModelAndView跳轉(zhuǎn)頁面失效的解決,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-05-05Spring Boot定時(shí)+多線程執(zhí)行過程解析
這篇文章主要介紹了Spring Boot定時(shí)+多線程執(zhí)行過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01Java實(shí)現(xiàn) 基于密度的局部離群點(diǎn)檢測------lof算法
這篇文章主要介紹了Java實(shí)現(xiàn) 基于密度的局部離群點(diǎn)檢測------lof算法,本文通過算法概述,算法Java源碼,測試結(jié)果等方面一一進(jìn)行說明,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07