834
技術社區[雲棲]
Java秘術:用枚舉構建一個狀態機
綜述
Java中的enum比其他的語言中的都強大,這產生了很多令人驚訝的用法。本文中,我將列出Java中的enum的一些特性,然後將這些特性應用到一起構成一個狀態機。
Enum的單例和工具類用法
你可以非常簡單地用一個enum構建一個單例或者工具類。
</pre>
enum Singleton {
INSTANCE;
}
enum Utility {
; // no instances
}
用enum實現一個接口
你也可以在一個enum中實現一個接口。
interface Named {
public String name();
public int order();
}
enum Planets implements Named {
Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune;
// name() is implemented automagically.
public int order() { return ordinal()+1; }
}
每一個enum實例,一個不同的子類
你可以重載一個enum實例的方法。這將高效的給一個enum的實例一個自己的實現。
// from https://download.oracle.com/javase/1,5.0/docs/guide/language/enums.html
public enum Operation {
PLUS { double eval(double x, double y) { return x + y; } },
MINUS { double eval(double x, double y) { return x - y; } },
TIMES { double eval(double x, double y) { return x * y; } },
DIVIDE { double eval(double x, double y) { return x / y; } };
// Do arithmetic op represented by this constant
abstract double eval(double x, double y);
}
使用一個enum實現一個狀態機
用上邊的技術,你可以做的是創建一個基於狀態的enum。
在這個小例子中,解析器的狀態機處理一個ByteBuffer裏的原始的XML。每一個狀態都有自己的處理方法,如果沒有足夠的可用的數據,狀態機可以回來再次獲取更多的數據。狀態之間的每一次變換都被定義,所有狀態的代碼在一個enum中。
interface Context {
ByteBuffer buffer();
State state();
void state(State state);
}
interface State {
/**
* @return true to keep processing, false to read more data.
*/
boolean process(Context context);
}
enum States implements State {
XML {
public boolean process(Context context) {
if (context.buffer().remaining() < 16) return false;
// read header
if(headerComplete)
context.state(States.ROOT);
return true;
}
}, ROOT {
public boolean process(Context context) {
if (context.buffer().remaining() < 8) return false;
// read root tag
if(rootComplete)
context.state(States.IN_ROOT);
return true;
}
}
}
public void process(Context context) {
socket.read(context.buffer());
while(context.state().process(context));
}
使用這種方式,可以創建一個XML解析器,解析器可以在10微秒內處理完數據包。大多數情況下,它跟你需要的一樣高效。
Reference: Java Secret: Using an enum to build a State machine from our JCG partner Peter Lawrey at the Vanilla Java.
最後更新:2017-05-23 11:31:50