自己一直以在都是這麼用 enum 的:
// 以下代碼出自 Java Tutorial
public enum Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY
}
....
Day day;
day = Day.SUNDAY;
把它當做一般的列舉型態來用. 而 enum 最大的便利就是可以用在 switch( ) ... case ... 語法上.
不過最近比較深入研究 enum 之後, 發現它其實是個 class, 可以擁有 constructor, method, 及 variable, 如此一來這樣可以做很多事.
下面寫一個簡單的範例示範其概念, FileType 列舉了二個檔案型態, 分別為 xls, csv, 不同的檔案型態各有其 parser 的實作. xls 的 parser class 是 ExcelParser, csv 的 parser class 是 CSVParser.
xls ( new ExcelParser() ) 意思是 xls 這個列舉值在建立時, 建立 ExcelParser instance 做為其 constructor 的參數. 因此, 在使用不同的 FileType 列舉值時, 就可以取得各自對應的 parser. 同樣的做法也可以運用在不同的 Action. 不但利於擴充, 也使得程式碼容易閱讀.
這個範例主要是展示運用字串取得對應的 FileType, 並執行其 parser, 取得結果. 完全不用 if ... else 來判斷, 有利於未來 FileType 種類的擴充, 或是在 FileType 相關邏輯的增加時, 可以寫在 FileType enum class 內.
public interface Parser {
public List parse(File file);
}
public enum FileType {
xls ( new ExcelParser() ),
csv ( new CSVParser() );
private Parser parser;
// constructor
FileType(Parser parser) {
this.parser = parser;
}
public Parser parser() { return this.parser; }
}
public void test(String typeName, File dataFile){
FileType fileType = FileType.valueOf(typeName);
List data = fileType.parser().parse(dataFile);
}
附註: 上述範例主要在展示概念, 沒實際測試過.
if ... else 的撰寫方式將與業務邏輯結合在一起, 容易模糊業務邏輯的焦點, 也不利於日後的維護及擴充.
我想, enum 與 class 的結合, 在實作 state machine 時, 會有很大的便利性. 一般以 class 實作 state machine 時, 會替每個 state 建立一個 class, 所有 state 都繼承自一個 base class, 這樣容易使得 class 變得很多, 類別佈局自然變得較複雜了.