那麼,如何消除在專案裡大量使用if-else呢?
網路上有很多解決思路,有工廠模式、策略模式、甚至是規則引擎(這個太重了吧)......
這些,都有一個共同的缺點,即使用起來還是過於繁重了。雖說避免出現過多的if-else,但是,卻增加很多額外的類,我總覺得,很不實用,只能當做某種模式的學習即可。
真正在專案中能替換大量if-else語句,且具備較好的可讀性與擴充套件性的,我比較推薦使用策略列舉來消除if-else。
假如有這樣一個需求,實現一週七天內分別知道要做事情的備忘功能,那麼,用if-else,可能是會這樣實現——
1 //if-else判斷
2 public String getToDoByIfElse(String day){
3 if("Monday".equals(day)){
4 return "今天上英語課";
5 }else if("Tuesday".equals(day)){
6 return "今天上語文課";
7 }else if("Wednesday".equals(day)){
8 return "今天上數學課";
9 }else if("Thursday".equals(day)){
10 return "今天上音樂課";
11 }else if{
12 return "今天上程式設計課";
13 }else{
14 ......
15 }
16 }
若要改成策略列舉模式,可直接這樣,首先,先定義一個呼叫方法,假如傳進的是星期一,即引數"Monday",在下面方法裡,通過DayEnum.valueOf("Monday")可獲取其列舉屬性,這裡應該得到的是Monday——
//策略列舉判斷,呼叫方法getToDoByEnum
public String getToDoByEnum(String day){
CheckDay checkDay=new CheckDay();
return checkDay.day(DayEnum.valueOf(day));
}
接下來,CheckDay()方法裡會做一個策略匹配,根據上面傳進來的DayEnum.valueOf("Monday"),即得到了列舉Monday,那麼,在這個方法裡,就會執行Monday.toDo()——
public class CheckDay {
public String day( DayEnum dayEnum) {
return dayEnum.toDo();
}
}
也就是執行Monday裡的toDo(),該列舉屬性當中實現了toDo()方法——
public enum DayEnum {
Monday {
@Override
public String toDo() {
return "今天上英語課";
}
},
Tuesday {
@Override
public String toDo() {
return "今天上語文課";
}
},
Wednesday {
@Override
public String toDo() {
return "今天上數學課";
}
},
Thursday {
@Override
public String toDo() {
return "今天上音樂課";
}
};
public abstract String toDo();
}
總結一下,策略列舉就是列舉當中使用了策略模式,所謂的策略模式,即給你一把鑰匙,按照某種約定的方式,可以立馬被指引找到可以開啟的門。例如,我給你的鑰匙叫“Monday”,那麼,就可以通過約定方式dayEnum.toDo(),立馬找到列舉裡的Monday大門,然後進到門裡,去做想做的事toDo(),其中,每扇門後的房間都有不同的功能,但它們都有一個相同抽象功能——toDo(),即各房間共同地方都是可以用來做一些事情的功能,但具體可以什麼事情,就各有不同了。
這裡,會出現一種情況,即,假如有多個重複共同樣功能的判斷話,例如,在if-else裡,是這樣——
public String getToDoByIfElse(String day){
if("Monday".equals(day)||"Tuesday".equals(day)||"Wednesday".equals(day)){
return "今天上英語課";
}else if("Thursday".equals(day)){
......
}
}
那麼,在策略列舉下應該如何使用從而避免程式碼冗餘呢?
可以參考一下以下思路,設定一個內部策略列舉,將有相同功能的外部引用指向同一個內部列舉屬性,這樣即可實現呼叫重複功能了——
public enum DayEnum {
//指向內部列舉的同一個屬性即可執行相同重複功能
Monday("星期一", Type.ENGLISH),
Tuesday("星期二", Type.ENGLISH),
Wednesday("星期三", Type.ENGLISH),
Thursday("星期四", Type.CHINESE);
private final Type type;
private final String day;
DayEnum(String day, Type type) {
this.day = day;
this.type = type;
}
String toDo() {
return type.toDo();
}
/**
* 內部策略列舉
*/
private enum Type {
ENGLISH {
@Override
public String toDo() {
return "今天上英語課";
}
},
CHINESE {
@Override
public String toDo() {
return "今天上語文課";
}
};
public abstract String toDo();
}
}
我很喜歡在大批量if-else裡使用策略列舉來消除替換,總而言之,使用策略列舉可以很靈活處理各種複雜判斷,且可讀性與擴充套件性都比較好,它更像是函數語言程式設計,而大批量if-else,則是程式導向了。因為,if-else是從上往下一個if接一個if判斷下去的,在各個if上打個斷點,debug下去,就明白了。
由此可知,若專案裡有大量的if-else話,著實是一件很影響效能的事情。