9個小技巧教你優(yōu)化臃腫的if_else,但有些人卻反對這么干
正文如下:
觀點一(靈劍):
前期迭代懶得優(yōu)化,來一個需求,加一個if,久而久之,就串成了一座金字塔。當代碼已經(jīng)復雜到難以維護的程度之后,只能狠下心重構(gòu)優(yōu)化。那,有什么方案可以優(yōu)雅的優(yōu)化掉這些多余的if/else?1. 提前return
這是判斷條件取反的做法,代碼在邏輯表達上會更清晰,看下面代碼:if?(condition)?{?//?do?something
}?else?{
??return?xxx;
}
其實,每次看到上面這種代碼,我都心里抓癢,完全可以先判斷
!condition
,干掉else。if?(!condition)?{??return?xxx;
}?
//?do?something
2. 策略模式
有這么一種場景,根據(jù)不同的參數(shù)走不同的邏輯,其實這種場景很常見。最一般的實現(xiàn):if?(strategy.equals("fast"))?{
??//?快速執(zhí)行
}?else?if?(strategy.equals("normal"))?{
??//?正常執(zhí)行
}?else?if?(strategy.equals("smooth"))?{
??//?平滑執(zhí)行
}?else?if?(strategy.equals("slow"))?{
??//?慢慢執(zhí)行
}
看上面代碼,有4種策略,有兩種優(yōu)化方案。
2.1 多態(tài)
interface?Strategy?{??void?run()?throws?Exception;
}
class?FastStrategy?implements?Strategy?{
????@Override
????void?run()?throws?Exception?{
????????//?快速執(zhí)行邏輯
????}
}
class?NormalStrategy?implements?Strategy?{
????@Override
????void?run()?throws?Exception?{
????????//?正常執(zhí)行邏輯
????}
}
class?SmoothStrategy?implements?Strategy?{
????@Override
????void?run()?throws?Exception?{
????????//?平滑執(zhí)行邏輯
????}
}
class?SlowStrategy?implements?Strategy?{
????@Override
????void?run()?throws?Exception?{
????????//?慢速執(zhí)行邏輯
????}
}
具體策略對象存放在一個Map中,優(yōu)化后的實現(xiàn)Strategy?strategy?=?map.get(param);
strategy.run();
上面這種優(yōu)化方案有一個弊端,為了能夠快速拿到對應的策略實現(xiàn),需要map對象來保存策略,當添加一個新策略的時候,還需要手動添加到map中,容易被忽略。
2.2 枚舉
發(fā)現(xiàn)很多同學不知道在枚舉中可以定義方法,這里定義一個表示狀態(tài)的枚舉,另外可以實現(xiàn)一個run方法。public?enum?Status?{????NEW(0)?{
??????@Override
??????void?run()?{
????????//do?something??
??????}
????},
????RUNNABLE(1)?{
??????@Override
???????void?run()?{
?????????//do?something??
??????}
????};
????public?int?statusCode;
????abstract?void?run();
????Status(int?statusCode){
????????this.statusCode?=?statusCode;
????}
}
重新定義策略枚舉public?enum?Strategy?{
????FAST?{
??????@Override
??????void?run()?{
????????//do?something??
??????}
????},
????NORMAL?{
??????@Override
???????void?run()?{
?????????//do?something??
??????}
????},
????SMOOTH?{
??????@Override
???????void?run()?{
?????????//do?something??
??????}
????},
????SLOW?{
??????@Override
???????void?run()?{
?????????//do?something??
??????}
????};
????abstract?void?run();
}
通過枚舉優(yōu)化之后的代碼如下Strategy?strategy?=?Strategy.valueOf(param);
strategy.run();
3. 學會使用 Optional
Optional主要用于非空判斷,由于是jdk8新特性,所以使用的不是特別多,但是用起來真的爽。使用之前:if?(user?==?null)?{????//do?action?1
}?else?{
????//do?action2
}
如果登錄用戶為空,執(zhí)行action1,否則執(zhí)行action 2,使用Optional優(yōu)化之后,讓非空校驗更加優(yōu)雅,間接的減少if操作Optional
userOptional.map(action1).orElse(action2);
4. 數(shù)組小技巧
來自google解釋,這是一種編程模式,叫做表驅(qū)動法,本質(zhì)是從表里查詢信息來代替邏輯語句,比如有這么一個場景,通過月份來獲取當月的天數(shù),僅作為案例演示,數(shù)據(jù)并不嚴謹。一般的實現(xiàn):int?getDays(int?month){????if?(month?==?1)??return?31;
????if?(month?==?2)??return?29;
????if?(month?==?3)??return?31;
????if?(month?==?4)??return?30;
????if?(month?==?5)??return?31;
????if?(month?==?6)??return?30;
????if?(month?==?7)??return?31;
????if?(month?==?8)??return?31;
????if?(month?==?9)??return?30;
????if?(month?==?10)??return?31;
????if?(month?==?11)??return?30;
????if?(month?==?12)??return?31;
}
優(yōu)化后的代碼int?monthDays[12]?=?{31,?29,?31,?30,?31,?30,?31,?31,?30,?31,?30,?31};
int?getDays(int?month){
????return?monthDays[--month];
}