防禦性程式設計失敗,我開始最佳化我寫的多重 if-else 程式碼
來源:Lorin 洛林
前言
• 最近防禦性程式設計比較火,不信邪的我在開發中進行了嘗試,然後我寫下了如下的程式碼:
public static void main(String[] args) {
// do something
if ("滿足條件A") {
// 查詢許可權
if ("是否具備許可權A" && "是否具備許可權B") {
// 查詢配置
if ("配置是否開啟"){
// do something
}
}
}
// do something
}
• 不出意外我被逮捕了,組內另外一位同事對我的程式碼進行了 CodeReview,我的防禦性程式設計程式設計沒有幸運逃脫,被標記上了“多重 if-else ”需要進行最佳化,至此我的第一次防禦性程式設計失敗,開始了最佳化多重 if-else 之路,下面是我總結出的常用幾種最佳化方式。
版本
• Java8
幾種常用的最佳化方式
提前使用 return 返回去除不必要的 else
• 如果我們的程式碼塊中需要使用 return 返回,我們應該儘可能早的使用 return 返回而不是使用 else
• 最佳化前
private static boolean extracted(boolean condition) {
if (condition) {
// do something
return false;
}else {
// do something
return true;
}
}
• 最佳化後
private static boolean extracted(boolean condition) {
if (condition) {
// do something
return false;
}
// do something
return true;
}
使用三目運算子
• 一些簡單的邏輯我們可以使用三目運算子替代 if-else ,這樣可以讓我們的程式碼更加簡潔
• 最佳化前
int num = 0;
if (condition) {
num = 1;
} else {
num = 2;
}
• 最佳化後
int num = condition ? 1 : 2;
使用列舉
• 在某一些場景我們也可以使用列舉來最佳化多重 if-else 程式碼,使我們的程式碼更加簡潔、具備更多的可讀性和可維護性。
• 最佳化前
String OrderStatusDes;
if (orderStatus == 0) {
OrderStatusDes = "訂單未支付";
} else if (orderStatus == 1) {
OrderStatusDes = "訂單已支付";
} else if (orderStatus == 2) {
OrderStatusDes = "已發貨";
} else {
throw new Exception("Invalid order status");
}
• 最佳化後
public enum OrderStatusEnum {
UN_PAID(0, "訂單未支付"),
PAIDED(1, "訂單已支付"),
SENDED(2, "已發貨"),
;
private final int code;
private final String desc;
public int getCode() {
return code;
}
public String getDesc() {
return desc;
}
OrderStatusEnum(int index, String desc) {
this.code = index;
this.desc = desc;
}
public static OrderStatusEnum getOrderStatusEnum(int orderStatusCode) {
for (OrderStatusEnum statusEnum : OrderStatusEnum.values()) {
if (statusEnum.getCode() == orderStatusCode) {
return statusEnum;
}
}
return null;
}
}
// 當然你需要根據業務場景對異常值做出合適的處理
OrderStatusEnum.getOrderStatusEnum(2)
抽取條件判斷作為單獨的方法
• 當我們某個邏輯條件判斷比較複雜時,可以考慮將判斷條件抽離為單獨的方法,這樣可以使我們主流程邏輯更加清晰
• 最佳化前
// do something
if ("滿足條件A" && "滿足條件B") {
// 查詢許可權
if ("是否具備許可權A" && "是否具備許可權B") {
// do something
}
}
// do something
• 最佳化後
public static void main(String[] args) {
// do something
if (hasSomePermission()) {
// do something
}
// do something
}
private static boolean hasSomePermission() {
if (!"滿足條件A" || !"滿足條件B") {
return false;
}
// 查詢許可權
return "是否具備許可權A" && "是否具備許可權B";
}
有時候 switch 比 if-else 更加合適
• 當條件為清晰的變數和列舉、或者單值匹配時,switch 比 if-else 更加合適,可以我們帶好更好的可讀性以及更好的效能 O(1)
• 最佳化前
if (day == Day.MONDAY) {
// 處理星期一的邏輯
} else if (day == Day.TUESDAY) {
// 處理星期二的邏輯
} else if (day == Day.WEDNESDAY) {
// 處理星期三的邏輯
} else if (day == Day.THURSDAY) {
// 處理星期四的邏輯
} else if (day == Day.FRIDAY) {
// 處理星期五的邏輯
} else if (day == Day.SATURDAY) {
// 處理星期六的邏輯
} else if (day == Day.SUNDAY) {
// 處理星期日的邏輯
} else {
// 處理其他情況
}
• 最佳化後
// 使用 switch 處理列舉型別
switch (day) {
case MONDAY:
// 處理星期一的邏輯
break;
case TUESDAY:
// 處理星期二的邏輯
break;
// ...
default:
// 處理其他情況
break;
}
策略模式 + 簡單工廠模式
• 前面我們介紹一些常規、比較簡單的最佳化方法,但是在一些更加複雜的場景(比如多渠道對接、多方案實現等)我們可以結合一些場景的設計模式來實現讓我們的程式碼更加優雅和可維護性,比如策略模式 + 簡單工廠模式。
• 最佳化前
public static void main(String[] args) {
// 比如我們商場有多個通知渠道
// 我們需要根據不同的條件使用不同的通知渠道
if ("滿足條件A") {
// 構建渠道A
// 通知
} else if ("滿足條件B") {
// 構建渠道B
// 通知
} else {
// 構建渠道C
// 通知
}
}
// 上面的程式碼不僅維護起來麻煩同時可讀性也比較差,我們可以使用策略模式 + 簡單工廠模式
• 最佳化後
import java.util.HashMap;
import java.util.Map;
// 定義通知渠道介面
interface NotificationChannel {
void notifyUser(String message);
}
// 實現具體的通知渠道A
class ChannelA implements NotificationChannel {
@Override
public void notifyUser(String message) {
System.out.println("透過渠道A傳送通知:" + message);
}
}
// 實現具體的通知渠道B
class ChannelB implements NotificationChannel {
@Override
public void notifyUser(String message) {
System.out.println("透過渠道B傳送通知:" + message);
}
}
// 實現具體的通知渠道C
class ChannelC implements NotificationChannel {
@Override
public void notifyUser(String message) {
System.out.println("透過渠道C傳送通知:" + message);
}
}
// 通知渠道工廠
class NotificationChannelFactory {
private static final Map<String, Class<? extends NotificationChannel>> channelMap = new HashMap<>();
static {
channelMap.put("A", ChannelA.class);
channelMap.put("B", ChannelB.class);
channelMap.put("C", ChannelC.class);
}
public static NotificationChannel createChannel(String channelType) {
try {
Class<? extends NotificationChannel> channelClass = channelMap.get(channelType);
if (channelClass == null) {
throw new IllegalArgumentException("不支援的通知渠道型別");
}
return channelClass.getDeclaredConstructor().newInstance();
} catch (Exception e) {
throw new RuntimeException("無法建立通知渠道", e);
}
}
}
// 客戶端程式碼
public class NotificationClient {
public static void main(String[] args) {
// 根據條件選擇通知渠道型別
String channelType = "A";
// 使用簡單工廠建立通知渠道
NotificationChannel channel = NotificationChannelFactory.createChannel(channelType);
// 執行通知
channel.notifyUser("這是一條通知訊息");
}
}
• 有時候我們還可以藉助 Spring IOC 能力的自動實現策略類的匯入,然後使用 getBean() 方法獲取對應的策略類例項,可以根據我們的實際情況靈活選擇。
如何最佳化開頭的程式碼
• 好了現在回到開頭,如果是你會進行怎麼最佳化,下面是我交出的答卷,大家也可以在評論區發表自己的看法,歡迎一起交流:
public static void main(String[] args) {
// do something
if (isMeetCondition()) {
// 查詢配置
// 此處查詢配置的值需要在具體的任務中使用,所有並沒抽離
if ("配置是否開啟") {
// do something
}
}
// do something
}
/**
* 判斷是否滿足執行條件
*/
private static boolean isMeetCondition() {
if (!"滿足條件A") {
return false;
}
// 查詢許可權
return "是否具備許可權A" && "是否具備許可權B";
}
來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70024922/viewspace-3004148/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 別讓“防禦性程式設計”毀了我們的職業程式設計
- 追求程式碼質量: 用 AOP 進行防禦性程式設計程式設計
- 你的程式設計能力從什麼時候開始突飛猛進? 我的回答:2013年,我開始喜歡程式設計了。程式設計
- 開啟我的程式設計之路程式設計
- 程式設計師毒雞湯:我們都該學會正確的失敗程式設計師
- 為了減少程式碼複雜度,我將if-else升級為面向狀態程式設計複雜度程式設計
- 學Guava發現:不可變特性與防禦性程式設計Guava程式設計
- 淺談軟體開發中的防禦式程式設計程式設計
- 我的程式設計之路程式設計
- 我的程式設計人生程式設計
- 防禦式程式設計之斷言assert的使用程式設計
- shell程式設計學習筆記(一):編寫我的第一段程式碼程式設計筆記
- Django 安全性與防禦性程式設計:如何保護 Django Web 應用Django程式設計Web
- 感悟我的程式設計之路程式設計
- 我的程式設計師之路程式設計師
- 我寫了本開源書:《3D程式設計模式》3D程式設計設計模式
- chatGPT幫我最佳化程式碼-2024.06.20ChatGPT
- git push程式碼失敗,鑑權失敗Git
- 使用 Angular Universal 進行伺服器端渲染的防禦性程式設計思路Angular伺服器程式設計
- 我打算寫一個《程式設計師的成長課》程式設計師
- 我的程式設計職業生涯程式設計
- Rust能讓我寫出好的程式碼 - RedditRust
- 我寫的 Python 程式碼,同事都說好Python
- 第一個想取代程式設計師的AI程式設計師,失敗了?程式設計師AI
- 3年程式設計師寫的程式碼被應屆生懟:我能三行搞定!也配叫程式設計師?程式設計師
- [譯] 我想學習程式設計, 但不知道從哪裡開始程式設計
- C/C++ 踩過的坑和防禦式程式設計C++程式設計
- 你好,我是程式設計師程式設計師
- 程式設計師入職三個月,竟一行程式碼都沒提交:我愛程式碼,程式碼使我快樂程式設計師行程
- 越早開始程式設計,程式越長程式設計
- 開發者故事|程式碼虐我千萬遍,我待程式碼如“初戀”
- 程式設計師朋友們,請答應我?別再去東南亞寫程式碼了好麼?程式設計師
- 無程式碼開發讓程式設計師面臨失業?程式設計師
- IT程式設計師的抉擇:我要離開帝都了程式設計師
- 現在,開始用嘴寫程式碼!
- VUE起手式-如何開始寫程式碼Vue
- 程式設計靠天分?不!我學程式設計靠風變程式設計
- 我為我是個程式設計師而驕傲程式設計師