if-else代碼優化的八種方案

2020-12-14 Java技術架構

作者:Jay_huaxiao來源:掘金 連結:https://juejin.im/post/5e5fa79de51d45271849e7bd

前言

代碼中如果if-else比較多,閱讀起來比較困難,維護起來也比較困難,很容易出bug,接下來,本文將介紹優化if-else代碼的八種方案。

優化方案一:提前return,去除不必要的else

如果if-else代碼塊包含return語句,可以考慮通過提前return,把多餘else幹掉,使代碼更加優雅。

優化前:

if(condition){ //doSomething}else{ return ;}優化後:

if(!condition){ return ;}//doSomething優化方案二:使用條件三目運算符

使用條件三目運算符可以簡化某些if-else,使代碼更加簡潔,更具有可讀性。

優化前:

int price ;if(condition){ price = 80;}else{ price = 100;}優化後:

int price = condition?80:100;優化方案三:使用枚舉

在某些時候,使用枚舉也可以優化if-else邏輯分支,按個人理解,它也可以看做一種表驅動方法

優化前:

String OrderStatusDes;if(orderStatus==0){ OrderStatusDes ="訂單未支付";}else if(OrderStatus==1){ OrderStatusDes ="訂單已支付";}else if(OrderStatus==2){ OrderStatusDes ="已發貨"; }...優化後:

先定義一個枚舉

public enum OrderStatusEnum { UN_PAID(0,"訂單未支付"),PAIDED(1,"訂單已支付"),SENDED(2,"已發貨"),; private int index; private String desc; public int getIndex() { return index; } public String getDesc() { return desc; } OrderStatusEnum(int index, String desc){ this.index = index; this.desc =desc; } OrderStatusEnum of(int orderStatus) { for (OrderStatusEnum temp : OrderStatusEnum.values()) { if (temp.getIndex() == orderStatus) { return temp; } } return null; }}有了枚舉之後,以上if-else邏輯分支,可以優化為一行代碼

String OrderStatusDes = OrderStatusEnum.0f(orderStatus).getDesc();優化方案四:合併條件表達式

如果有一系列條件返回一樣的結果,可以將它們合併為一個條件表達式,讓邏輯更加清晰。

優化前

double getVipDiscount() { if(age<18){ return 0.8; } if("深圳".equals(city)){ return 0.8; } if(isStudent){ return 0.8; } //do somethig }優化後

double getVipDiscount(){ if(age<18|| "深圳".equals(city)||isStudent){ return 0.8; } //doSomthing }優化方案五:使用 Optional

有時候if-else比較多,是因為非空判斷導致的,這時候你可以使用java8的Optional進行優化。

優化前:

String str = "jay@huaxiao";if (str != null) { System.out.println(str);} else { System.out.println("Null");}優化後:

Optional<String> strOptional = Optional.of("jay@huaxiao");strOptional.ifPresentOrElse(System.out::println, () -> System.out.println("Null"));優化方案六:表驅動法

表驅動法,又稱之為表驅動、表驅動方法。表驅動方法是一種使你可以在表中查找信息,而不必用很多的邏輯語句(if或Case)來把它們找出來的方法。以下的demo,把map抽象成表,在map中查找信息,而省去不必要的邏輯語句。

優化前:

if (param.equals(value1)) { doAction1(someParams);} else if (param.equals(value2)) { doAction2(someParams);} else if (param.equals(value3)) { doAction3(someParams);}// ...優化後:

Map<?, Function<?> action> actionMappings = new HashMap<>(); // 這裡泛型 ? 是為方便演示,實際可替換為你需要的類型// 初始化actionMappings.put(value1, (someParams) -> { doAction1(someParams)});actionMappings.put(value2, (someParams) -> { doAction2(someParams)});actionMappings.put(value3, (someParams) -> { doAction3(someParams)});// 省略多餘邏輯語句actionMappings.get(param).apply(someParams);優化方案七:優化邏輯結構,讓正常流程走主幹

優化前:

public double getAdjustedCapital(){ if(_capital <= 0.0 ){ return 0.0; } if(_intRate > 0 && _duration >0){ return (_income / _duration) *ADJ_FACTOR; } return 0.0;}優化後:

public double getAdjustedCapital(){ if(_capital <= 0.0 ){ return 0.0; } if(_intRate <= 0 || _duration <= 0){ return 0.0; } return (_income / _duration) *ADJ_FACTOR;}將條件反轉使異常情況先退出,讓正常流程維持在主幹流程,可以讓代碼結構更加清晰。

優化方案八:策略模式+工廠方法消除if else

假設需求為,根據不同勳章類型,處理相對應的勳章服務,優化前有以下代碼:

String medalType = "guest"; if ("guest".equals(medalType)) { System.out.println("嘉賓勳章"); } else if ("vip".equals(medalType)) { System.out.println("會員勳章"); } else if ("guard".equals(medalType)) { System.out.println("展示守護勳章"); } ...首先,我們把每個條件邏輯代碼塊,抽象成一個公共的接口,可以得出以下代碼:

//勳章接口public interface IMedalService { void showMedal();}我們根據每個邏輯條件,定義相對應的策略實現類,可得以下代碼:

//守護勳章策略實現類public class GuardMedalServiceImpl implements IMedalService { @Override public void showMedal() { System.out.println("展示守護勳章"); }}//嘉賓勳章策略實現類public class GuestMedalServiceImpl implements IMedalService { @Override public void showMedal() { System.out.println("嘉賓勳章"); }}//VIP勳章策略實現類public class VipMedalServiceImpl implements IMedalService { @Override public void showMedal() { System.out.println("會員勳章"); }}接下來,我們再定義策略工廠類,用來管理這些勳章實現策略類,如下:

//勳章服務工產類public class MedalServicesFactory { private static final Map<String, IMedalService> map = new HashMap<>(); static { map.put("guard", new GuardMedalServiceImpl()); map.put("vip", new VipMedalServiceImpl()); map.put("guest", new GuestMedalServiceImpl()); } public static IMedalService getMedalService(String medalType) { return map.get(medalType); }}使用了策略+工廠模式之後,代碼變得簡潔多了,如下:

public class Test { public static void main(String[] args) { String medalType = "guest"; IMedalService medalService = MedalServicesFactory.getMedalService(medalType); medalService.showMedal(); }}

相關焦點

  • 編寫if 時不帶 else,你的代碼會更好!
    本文轉載自【微信公眾號:五角錢的程式設計師,ID:xianglin965】經微信公眾號授權轉載,如需轉載與原文作者聯繫設計更好的軟體,替換If-Else的5種方法。入門到高級示例讓我直接說這句話:If-Else通常是一個糟糕的選擇。
  • 求求你們了,別再寫滿屏的 if/ else 了
    為什麼我們寫的代碼都是 if-else?程式設計師想必都經歷過這樣的場景:剛開始自己寫的代碼很簡潔,邏輯清晰,函數精簡,沒有一個 if-else,可隨著代碼邏輯不斷完善和業務的瞬息萬變:比如需要對入參進行類型和值進行判斷;這裡要判斷下對象是否為 null;不同類型執行不同的流程。
  • 徹底消滅if-else嵌套
    但if-else一般不建議嵌套超過三層,如果一段代碼存在過多的if-else嵌套,代碼的可讀性就會急速下降,後期維護難度也大大提高。2.2 親歷的重構前陣子重構了服務費收費規則,重構前的if-else嵌套如下。
  • if (你看這篇文章) 你會獲得一些if優化技巧,else 寫不好if
    最近在代碼review的過程中發現了一些問題,這些問題雖然不影響邏輯,但是對代碼的可讀性,安全性留下了隱患。今天這篇文章寫在紙上寫了好多天,一直放在口袋裡,一直工作比較忙沒時間寫,今天加個班寫一下。if 是每個語言都有的語法,也是最基礎的語法。因為代碼本來就很晦澀,所以才有了程式設計師這個中間件,碼農。怎麼樣才能寫出好讀的,不容易出錯的代碼?不人為的增加代碼的難度吶?
  • VBA中的If-Then-Else語句
    [ elseifstatements ]][ Else[ elsestatements ]]End If各個參數的作用:① condition 必需。④ elseifstatements 可選。 如果關聯condition-n為True, 則執行一個或多個語句。⑤ elsestatements 可選。 如果前一個condition或condition-n表達式為True, 則執行的一個或多個語句。2)塊格式的If語句必須是行上的第一個語句。
  • 如果明天下雨我就不去上班啦(PHP if...else...elseif 語句)
    路同聊江湖 舉報   PHP 條件語句:條件語句用於基於不同條件執行不同的動作,我們編寫代碼時
  • 是時候和else關鍵字說再見了……
    筆者在開始編程的時候,最大錯誤之一是在編寫條件句時過度使用else關鍵字,早五年前筆者就告別else了。原因何在呢?想一下else是什麼意思,其意為「如果滿足A就執行這個,如果不滿足A就執行那個」。避免if/else if,只使用if語句,花時間確保if組的輸入條件是互斥的,這樣答案就不依賴於執行順序了。· 使用switch — case語句· 使用多態性處理複雜的條件情況,使代碼更像狀態模式。
  • 使用if-else進行分支的方法已過時,分析多態性和現代方法更合適
    if-else和switch當然可以生成簡潔的代碼,你的軟體不應該由最少的行組成,也不必犧牲可讀性、可維護性或靈活性。在if-then-else語句中使用枚舉的後果是什麼呢?基於離散值的分支會使軟體難以更改。每個新功能都要求跟蹤分支發生的位置,並相應地修改現有代碼。這絕對不是我們想要的方式。
  • 基礎不牢地動山搖記住 Java 面試中常用的八種排序算法與代碼實現
    代碼實現如下:public void insertSort(int[] a){int length=a.length;//數組長度,將這個提取出來是為了提高速度。} a[position]=a[i];//交換位置 a[i]=key; } }4.堆排序對簡單選擇排序的優化
  • 詳解一種端遊遊戲代碼保護方案
    對於關鍵函數的定位,這裡又分兩種情況:第一種情況是遊戲邏輯相關的代碼就是原生的機器碼,如Unity3D IL2CPP及UE4。攻擊者往往會選擇靜態分析結合動態調試的形式來分析遊戲邏輯,此時傳統代碼保護可以起到比較好的防禦效果,大大提高攻擊者分析遊戲邏輯的時間成本,而且對於大部分攻擊者而言,這個時間成本是不可估量的。
  • Java代碼的優化方法有哪些
    說到代碼優化,每個人或多或少都掌握一到兩種方法,但是這樣的方法對提升代碼運行效率效果不大,最重要是對代碼的重視和了解,這樣才能提升代碼的運行效率。在進行代碼優化的過程中,方法是非常重要的,多掌握幾種方法,根據代碼的不同情況選擇適合的方法進行優化。
  • 《第4章 Python 流程控制語語句》4.2.3 if……elif……else語句!
    《高中信息技術 Python編程》 教學案《第4章 Python 流程控制語語句》4.2.3 if...elif...else語句!(3)if....elif....else....形式語法格式如下:if 條件1:條件1滿足執行的代碼elif 條件2:條件2滿足時執行的代碼.....................
  • 百行 HTML5 代碼實現四種雙人對弈遊戲
    HTML5 框架下,有至少 3 種方法:第一種,用 Canvas 畫線;第二種,用 DIV,CSS3 裡面增加了行列屬性;第三種,用 table 標籤。        用哪一種速度最快,代碼少呢?答案是:第三種。多少有點失望啊,HTML5 不是萬能的。
  • python入門第十三課:文件的讀寫與分析介紹,異常處理和代碼重構
    ='UTF-8') as file_object:file_object.write('這是我第一個寫文件')1、open()函數多了個參數『w』,這是告訴open()函數,用寫模式打開這個文件,下面是幾種常見的打開模式:
  • 網站編程錦上添花 分享8個常用代碼優化小助手
    而代碼又是編程的主要途徑。代碼優化是通過對程序代碼進行等價變化,而不改變程序的運行結果。常用的代碼優化技術有刪除多餘運算,循環不變代碼外提,強度削弱等。下面,IDC評述網與大家分享8個代碼優化小助手,供參考。1. JalopyJalopy是一個 Java 原始碼格式化工具,它可以使用一套可配置的布局規則修改 Java 原始碼的布局。2.
  • Babel是如何讀懂JS代碼的
    Babel工作的三個階段首先要說明的是,現在前端流行用的WebPack或其他同類工程化工具會將源文件組合起來,這部分並不是Babel完成的,是這些打包工具自己實現的,Babel的功能非常純粹,以字符串的形式將原始碼傳給它,它就會返回一段新的代碼字符串(以及sourcemap)。
  • 直播app原始碼,在網際網路領域務必要做好優化工作
    這其中對於直播app原始碼來說更是需要不斷的進行更新優化。二、多方位分析直播app原始碼優化的原因1. 保證軟體穩定運行保持對直播app原始碼的優化更新,可以避免搭建部署後的直播app出現運行BUG或者運行故障的問題,以免耽誤直播軟體的正常使用。
  • 直播平臺原始碼的基礎功能和首屏優化,小白必看點
    直播平臺原始碼從字面意思來看就是指開發者開發直播軟體的程序代碼。對於任何一個程序軟體來說,程序代碼都是至關重要的,所以在搭建直播平臺的時候,直播平臺原始碼顯得尤為重要。
  • 《前端5分鐘》之迭代器模式的N+1種應用場景
    == undefined) {result = result[key[i]]}else {return undefined}}return resultbreak;default:break;}}return data}由以上分析可知,上面的代碼還有很多優化空間
  • DSP編程技巧之15-使用代碼優化時必須考慮的五大問題
    俗話說「好馬配好鞍」,即使我們有了強大的代碼優化工具,使得我們書寫的符合ANSI/ISO C/C++的代碼能被高效執行,我們在寫代碼時也要考慮到一些必要的原則,從而既能實現代碼的優化,也能保證代碼的安全,使得優化操作不會讓我們的代碼產生預期之外的結果。下面我們就來看一下在使用代碼優化時,必須考慮的五大問題。