枚舉應該都有用過,枚舉主要的作用是為了方便用戶查找和引用枚舉。
案例一
下面的枚舉邏輯很簡單,就是通過枚舉值返回不同的結果。
public enum OperationEnum {EQUAL_TO,CONTAINS,START_WITH,END_WITH;public String getOperationValue(String value) {if (this == EQUAL_TO) {return "'" + value + "'";} else if (this == START_WITH) {return "/" + value + ".*/";} else if (this == END_WITH) {return "/" + value + ".*/";} else {return "/.*" + value + ".*/";}}
}
學了《設計模式》之后,我們很容易看出這段代碼的問題。
代碼中getOperationValue
里使用if...else...
的結構,導致枚舉值之間存在耦合關系。
舉個例子來說,當我們要增加新的枚舉值時需要修改這段if...else...
代碼。
那么明顯它沒有符合低耦合 高內聚
的設計理念。
我們也都知道,抽象比具體 更穩定
那為了避免使用if...else...
結構,我們將getOperationValue
定義為抽象方法,如下
通過重載抽象方法進行解耦
enum OperationEnum {EQUAL_TO {@Overridepublic String getOperationValue(String value) {return "'" + value + "'";}},CONTAINS {@Overridepublic String getOperationValue(String value) {return "/.*" + value + ".*/";}},START_WITH {@Overridepublic String getOperationValue(String value) {return "/" + value + ".*/";}},END_WITH {@Overridepublic String getOperationValue(String value) {return "/.*" + value + "/";}};/*** 定義抽象方法*/public abstract String getOperationValue(String value);
}
我們對比前后的代碼,很明顯,新增枚舉時,帶抽象方法重載的方式影響更小。
是否覺得上述代碼已經足夠好了?
利用接口的方式實現枚舉
import java.util.function.Function;public enum OperationEnum {EQUAL_TO((value) -> "'" + value + "'"),CONTAINS((value) -> "/.*" + value + ".*/"),START_WITH((value) -> "/" + value + ".*/"),END_WITH((value) -> "/.*" + value + "/");private final Function<String, String> function;OperationEnum(Function<String, String> function) {this.function = function;}public String getOperationValue(String value) {return function.apply(value);}
}
如果邏輯足夠簡單,從代碼來說這種代碼更簡潔明了。
如果邏輯比較復雜,可以將lambda表達式用接口實現類代替,然后構造的時候傳入對應的接口實現