Java秘术:用枚举构建一个状态机

原文链接   作者:Peter Lawrey    译者:陈振阳

综述

Java中的enum比其他的语言中的都强大,这产生了很多令人惊讶的用法。本文中,我将列出Java中的enum的一些特性,然后将这些特性应用到一起构成一个状态机。

Enum的单例和工具类用法

你可以非常简单地用一个enum构建一个单例或者工具类。

1</pre>
2enum Singleton {
3    INSTANCE;
4}
5enum Utility {
6    ; // no instances
7}

用enum实现一个接口

你也可以在一个enum中实现一个接口。

1interface Named {
2    public String name();
3    public int order();
4}
5enum Planets implements Named {
6    Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune;
7    // name() is implemented automagically.
8    public int order() { return ordinal()+1; }
9}

每一个enum实例,一个不同的子类

你可以重载一个enum实例的方法。这将高效的给一个enum的实例一个自己的实现。

01// from http://download.oracle.com/javase/1,5.0/docs/guide/language/enums.html
02public enum Operation {
03  PLUS   { double eval(double x, double y) { return x + y; } },
04  MINUS  { double eval(double x, double y) { return x - y; } },
05  TIMES  { double eval(double x, double y) { return x * y; } },
06  DIVIDE { double eval(double x, double y) { return x / y; } };
07 
08  // Do arithmetic op represented by this constant
09  abstract double eval(double x, double y);
10}

使用一个enum实现一个状态机

用上边的技术,你可以做的是创建一个基于状态的enum。

在这个小例子中,解析器的状态机处理一个ByteBuffer里的原始的XML。每一个状态都有自己的处理方法,如果没有足够的可用的数据,状态机可以回来再次获取更多的数据。状态之间的每一次变换都被定义,所有状态的代码在一个enum中。

01interface Context {
02    ByteBuffer buffer();
03    State state();
04    void state(State state);
05}
06interface State {
07    /**
08       * @return true to keep processing, false to read more data.
09     */
10    boolean process(Context context);
11}
12enum States implements State {
13    XML {
14        public boolean process(Context context) {
15            if (context.buffer().remaining() < 16) return false;
16            // read header
17            if(headerComplete)
18                context.state(States.ROOT);
19            return true;
20        }
21    }, ROOT {
22        public boolean process(Context context) {
23            if (context.buffer().remaining() < 8) return false;
24            // read root tag
25            if(rootComplete)
26                context.state(States.IN_ROOT);
27            return true;
28        }
29    }
30}
31 
32public void process(Context context) {
33    socket.read(context.buffer());
34    while(context.state().process(context));
35}

使用这种方式,可以创建一个XML解析器,解析器可以在10微秒内处理完数据包。大多数情况下,它跟你需要的一样高效。

Reference: Java Secret: Using an enum to build a State machine from our JCG partner Peter Lawrey at the Vanilla Java.

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值