聊聊java中一些減少if else 的編碼習慣的方法
前言
前段時間在閱讀別人所寫的代碼的時候 , 發(fā)現其中一些業(yè)務相關的方法體內 , 出現了比較多的if-else語句多層嵌套的情況 . 首先我個人不是不提倡寫if-else語句 , 不得不說 , 很多時候 , 在寫某些邏輯 使用if-else 去做判斷 , 代碼看起來還是十分直觀的 , 但是如果濫用if-else , 形成多層嵌套或者形成, 其中每個case 還包含了大量的邏輯 , 此時從可讀性來說 , 使用if-else就有點得不償失了 . 而且某些時候 , 可能并不需這么多的if-else , 或者是可以使用其他編碼方式從而達到減少的if-else 的效果 .
減少if-else 的使用的方式有很多 , 例如設計模式層面的策略模式或者是責任鏈模式 . 而這里跟大家分享一下一些個人在日常編碼過程中經常用到的 , 比較簡單的 、從編碼習慣層面上的方式 , 去一些減少不必要if-else使用 . 由于本人只是一個小菜鳥 , 如果有寫得不對的地方 , 懇請批評指正 .
一些減少if-else的編碼方式
方式一 : 提前return
首先展示一段代碼示例 :
if (condition1) { if (condition2) { return getSomething(); } else { return 0; } } else { return 0; }
修改后的代碼如下 :
//這里最好對這個flag所判斷的邏輯補充注釋進行描述 boolean flag = !condition1 || (condition1 && !condition2) if(flag) { return 0; } if (condition1 && condition2) { return getSomething(); }
如果存在已知在某些條件下 , 需要返回固定值的邏輯 , 可以將這部分邏輯抽取為一個獨立的 if-else block , 并置于其他if-else block的前面 , 當符合該特定條件時 , 直接提前 return 固定值 . 這種方式最直接的效果就是降低if-else的嵌套數量 .
方式二 : 使用三目運算符
先上例子 , 這里以一個業(yè)務場景為例 :
查詢某條評論的圖片URL列表 (如果有 , 評論的圖片url列表以JSON數組字符串格式保存在評論表中)
修改前的代碼如下 :
Comment comment = getById(commentId); if (Objects.isNull(comment)) { throw new RuntimeException("評論不存在或已被刪除"); } String imgListStr = comment.getImgList(); if(StringUtils.isEmpty(imgListStr)) { return null; } return JSON.parseArray(imgListStr, String.class);
修改后 :
Comment comment = getById(commentId); if (Objects.isNull(comment)) { throw new RuntimeException("評論不存在或已被刪除"); } String imgListStr = comment.getImgList(); return StringUtils.isEmpty(imgListStr)) ? null : JSON.parseArray(imgListStr, String.class);
方式三 : 使用Assert斷言
在編寫業(yè)務代碼過程中 , 如果需要對某些特定的條件進行判斷 , 且當條件不滿足時需要拋出異常 . 對于這種場景 , 除了使用上面三目運算符的示例當中的if方式 , 還可以通過使用Spring Framework 給我們提供的 Assert 工具類進行 .
其中常用的API 有 :
- isTrue(boolean expression , String message) : 當expressio == false時 , 會拋出異常 , 異常的message則為第二個入參 ;
- void notNull(@Nullable Object object, String message) : 同上 , 當object == null 時 , 會拋出異常;
- void notEmpty(@Nullable Collection<?> collection, String message) : 同上 , 當集合對象為null或者集合元素為空時 , 會拋出異常 .
- .....
還有其他較多方法 , 可以直接看源碼的解析 , 當然實際上isTrue() 已經夠用了 , 如果需要更加的語義化 , 可以使用對應的API .
修改前代碼 :
if (Objects.isNull(comment)) { throw new RuntimeException("評論不存在或已被刪除"); }
修改后代碼 :
Assert.isTrue(Objects.nonNull(comment),"評論不存在或已被刪除"); Assert.notNull(comment,"評論不存在或已被刪除");
目前Assert工具方法只能拋出單一一種異常 java.lang.IllegalArgumentException , 如果需要自定義所拋出的異常 , 則該方式不適用 .
方式四 : 使用Optional
Optional是 java8 的新特性 , 相當于一個對象的容器 , 主要用于對象的null值校驗 , 以及在進行校驗后可鏈式地進行后續(xù)操作 , 如 : 拋出異常、null替換 等 .
其中我個人比較常用的幾個方法為 :
- static <T> Optional<T> ofNullable(T value) : 使用Optional 將對象進行包裹 ;
- T orElse(T other) : Optional中的對象為null時 ,返回入參的對象 .
- T orElseGet(Supplier<? extends T> other) : Optional中的對象為null時 , 返回Supplier 提供的值 ;
- T orElseThrow(Supplier<? extends X> exceptionSupplier) : Optional中的對象為null時 , 拋出supplier提供的自定義異常
代碼示例 :
Message message1 = Optional.ofNullable(getById(messageId)) .orElseThrow(() -> new RuntimeException("消息不存在!")); Message message2 = Optional.ofNullable(getById(messageId)) .orElse(new Message()); Message message3 = Optional.ofNullable(getById(messageId)) .orElseGet(Message::new);
由于我日常需要的進行空值判斷的比較多的場景是從數據庫查詢數據完畢時 , 需要查詢結果進行空值判斷 . 由于我所在的公司使用的持久層框架是mybatis , 不像Spirng Boot 2.x 默認版本的JPA 那樣DAO層方法支持返回值為Optional , 所以這里如果需要使用Optional , 只能手動去使用上面列舉的第一個方法對查詢結果進行包裝 .
當然 , IDEA其實已經給我們提供了該包裝方式的熱鍵了 , 如下圖所示 :
結語
個人的一些減少if-else 編碼習慣分享就這里了 , 這幾種方式里面 , 我個人覺得效果最明顯的還是第一種 提前return , 很多時候 , 提前return 也可以很好降低一段代碼的復雜度 .
當然如果必須要使用大量的if-else 去控制邏輯時 , 在每個condition 標明一下注釋還是一個挺不錯的習慣 .
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
自從在 IDEA 中用了熱部署神器 JRebel 之后,開發(fā)效率提升了 10(真棒)
在javaweb開發(fā)過程中,使用熱部署神器 JRebel可以使class類還是更新spring配置文件都能立馬見到效率,本文給大家介紹JRebel的兩種安裝方法,小編建議使用第二種方法,具體安裝步驟跟隨小編一起看看吧2021-06-06詳解Springboot之整合JDBCTemplate配置多數據源
這篇文章主要介紹了詳解Springboot之整合JDBCTemplate配置多數據源,文中有非常詳細的代碼示例,對正在學習java的小伙伴們有很好的幫助,需要的朋友可以參考下2021-04-04