<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在日常開發中我們常常遇到有多個if else的情況,之間書寫顯得程式碼冗餘難看,對於追求更高質量程式碼的同學,就會思考如何優雅地處理這種程式碼
下面我們來探討下幾種優化if else的方法
switch方法針對列舉值處理有不錯的效果,比如針對不同的訂單狀態時要做不同的處理,因為狀態值有限,這時我們就可以直接使用switch來針對不同狀態做不同的處理:
原語句
public void before(Integer status) { if(status == 1){ System.out.println("訂單未接單"); }else if(status == 2){ System.out.println("訂單未發貨"); }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("訂單未發貨"); break; case 3: System.out.println("訂單未簽收"); break; default: System.out.println("訂單已簽收"); } }
總結:
switch語句適用於判斷條件有限且不需要經過複雜的計算,處理語句簡單的場景。如果我們的判斷條件需要經過一系列複雜的計算才能得到,或者處理語句邏輯也比較複雜時,我們就要考慮其他的處理方式了,畢竟在case中書寫一大堆處理語句並不算得讓人舒適的事情
針對比較複雜的處理邏輯時,我們偏向於將這些處理邏輯單獨抽離出來,而不是還放在一個方法裡處理,增加整體的可讀性和解耦性,也是我們衍生出利用函數式介面來處理if else的模式
函數式介面map處理if else的要義,是將各個條件的複雜處理邏輯單獨抽取為一個函數式介面方法,通過統一的判斷條件來呼叫不同的方法,具體範例如下
@Component public class FunctionInterfaceStrategy { /** * key 方法引數,多個引數可以自定義一個實體類處理 * 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 比較複雜的處理邏輯 System.out.println("訂單未接單"); return true; } private Boolean sendOrder(Object params){ // TODO 比較複雜的處理邏輯 System.out.println("訂單未發貨"); return true; } private Boolean signOrder(Object params){ // TODO 比較複雜的處理邏輯 System.out.println("訂單未簽收"); return true; } private Boolean finishOrder(Object params){ // TODO 比較複雜的處理邏輯 System.out.println("訂單已簽收"); return true; } }
呼叫時就不用再用if else區分了,直接傳入引數到function map中呼叫
@Autowired private FunctionInterfaceStrategy functionInterfaceStrategy; functionInterfaceStrategy.doOperation("引數",1);
當然我們上述演示的是有引數有返回值的函數式介面,實際生產中我們可能還需要其他形式的函數式介面,我們將其單獨羅列出來,供大家參考使用
介面名稱 | 說明 | 呼叫方法 |
---|---|---|
Supplier | 無引數,有返回值 | get |
Consumer | 有引數,無返回值 | accept |
Runnable | 無引數,無返回值 | run |
Function | 有引數,有返回值 | apply |
上述的函數式介面的形式,實際上是針對方法進行了分離,所有的實現方法還是放在了一個類裡,即使你可以在FunctionInterfaceStrategy類中通過依賴注入的形式再次呼叫其他類的方法,但是這樣的模式,已經趨近於我們要將的下一種方法,即使用策略模式來解決 if else
策略模式的形式適用於實現方法更加複雜的情況,需要將處理邏輯解耦的更加乾淨的場景
1、首先我們需要建立一個介面類,用來規定我們後續的實現類的格式
public interface OrderStrategy { /** * 獲取實現類標識 * @return */ Integer getType(); /** * 邏輯處理 * @param params * @return */ Boolean handler(Object params); }
2、其次針對每個判斷條件建立一個實現類
@Service public class SendOrderStrategy implements OrderStrategy{ @Override public Integer getType() { return 2; } @Override public Boolean handler(Object params) { // TODO 複雜的處理邏輯 System.out.println("訂單未發貨"); return true; } } @Service public class SignOrderStrategy implements OrderStrategy{ @Override public Integer getType() { return 3; } @Override public Boolean handler(Object params) { // TODO 複雜的處理邏輯 System.out.println("訂單未簽收"); return true; } } @Service public class TakeOrderStrategy implements OrderStrategy{ @Override public Integer getType() { return 1; } @Override public Boolean handler(Object params) { // TODO 複雜的處理邏輯 System.out.println("訂單未接單"); return true; } }
3、建立一個策略工廠類,承裝實現類
@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); } } /** * 執行方法 * @param status * @param params * @return */ public Boolean handler(Integer status,Object params){ return strategyMap.get(status).handler(params); } }
4、方法呼叫
@RestController @RequestMapping("ifelse") @AllArgsConstructor public class IfElseController { private final OrderStrategyFactory orderStrategyFactory; @GetMapping("strategy") public Boolean strategy(Integer status){ return orderStrategyFactory.handler(status,"1"); } }
總結:
通過上述的程式碼範例,大家其實可以發現,函數式介面和策略模式有異曲同工之處,根本區別在於是否需要將實現方法單獨抽取為一個實現類。抽取的粒度越細也就說明解耦越強
使用策略模式,後續如果需要增加if else條件的話,只需要增加實現類即可,針對後續的處理更加方便
最終使用哪一個還需要根據具體的業務情況而定
我們經常需要在方法前處理各種引數巢狀判斷邏輯,如果不滿足條件就直接返回了,這種情況更加推薦使用衛語句來處理
原語句
public void before(Integer status) { if(status != null) { if(status != 0){ if(status == 1){ System.out.println("訂單未接單"); } } } }
衛語句
public void greater(Integer status) { if(status == null){ return; } if(status != 0){ return; } if(status == 1){ System.out.println("訂單未接單"); } }
到此這篇關於詳解Java如何優雅地書寫if-else的文章就介紹到這了,更多相關Java if-else內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45