使用enum建立简单的状态机
Overview
The enum in Java is more powerful than many other languages which can lead to surprising uses.
In this article, I outline some the individual features of enum in Java, and put them together to form a state machine.
Enum for Singleton and Utility class
You can use an enum as a Singleton or Utility very simply.
enum Singleton {
INSTANCE;
}
enum Utility {
; // no instances
}
Enum to implement an interface
You can also implement an interface in an 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; }
}
Each Enum Instance a different sub-class
You can override the behaviour of an instance. This effectively give the instance a different sub-class of the enum with its own implementation.
// from http://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);
}
Using an enum as a state machine
What you can do with all these techniques is to create a enum based statement.

In this short example, a parser state machine processes raw XML from a ByteBuffer. Each state has its own process method and if there is not enough data available, the state machine can return to retrieve more data. Each transition between states is well defined and the code for all states is together in one 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));
}
写在后面
个人感觉使用如果想真的实现一个完整的finite-state machine的话,上面的例子真的是太基础了。不过参考上面的用法可以帮助我们减少很多的if else if等代码。另外涉及到“分支处理”的情况,在实际的工作中,我更多的还是会选择“策略模式”。
参考资料
使用enum建立简单的状态机的更多相关文章
- php建立简单的用户留言系统
php建立简单的用户留言系统 样例 addMsg.php--添加留言页面 doAction.php--响应添加留言页面 . viewMsg.php--显示留言页面 目录结构 addMsg.php--添 ...
- 用eclipse建立简单WebService客户端,使用WSDL,用于短信接口发送
使用工具:eclipse 标准版,不用任何插件. 操作步骤: 建立java Project 命名为mess: 再在project上右键,选择other,选择web service文件类别,选择web ...
- Springboot - 建立简单的用户登录系统
在开始编码前,先建立几个Package(可以按个人习惯命名),如图 1.Controllers 用于存放控制器类 2.Models 用于存放数据实体类 3.Repositories 用于存放数据库操作 ...
- mysql中set和enum使用(简单介绍)
简单介绍 SET类型 在创建表时,就指定SET类型的取值范围. 属性名 SET('值1','值2','值3'...,'值n') 其中,“属性名”参数指字段的名称:“值n”参数表示列表中的第n个值,这些 ...
- 基于jFinal建立简单的服务端-接收请求并返回指定内容
本菜鸡是一名弱弱的测试工程师,最近完成了一个支付相关的项目,项目工作中,需要建立一个模拟支付宝的网关,主要是接收请求并返回数据.作为一名没有丝毫开发经验的菜鸡,初期入门相当费劲,主要还是思维上的转变. ...
- node.js建立简单应用
1. 建立工程 进入工程目录 cd D:\workspace\project 全局安装express,express作为命令被安装到了系统中 npm install -g express 查看expr ...
- JavaScript 建立简单的图片库
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...
- Enum枚举 简单的使用
在枚举中使用抽象方法 /** * 为枚举类定义一个抽象方法,<br/> * 这个抽象方法由不同的枚举值提供不同的实现 * * @author wangzhu * @date 2014-9- ...
- 建立简单的VLAN通信
http://minitoo.blog.51cto.com/4201040/786011(转载) 在路由器上做单臂路由实现VLAN间路由,也就是设置子接口和封装协议. 实现环境如下图: 在交换机上建立 ...
随机推荐
- GET请求参数为中文时乱码分析
问题描述 近期做任务时,跟后端联调时遇到一个问题,前端发送get请求,当参数值有中文时,请求失败,请求参数变为乱码.(ps:一般当参数有中文时,很少使用get请求,而是使用post请求来传输数据,请求 ...
- springmvc 通过异常增强返回给客户端统一格式
在springmvc开发中,我们经常遇到这样的问题:逻辑正常执行时返回客户端指定格式的数据,比如json,但是遇NullPointerException空指针异常,NoSuchMethodExcept ...
- 如何禁止IE自动生成链接
今天一位园友反馈,他用的是IE浏览器,在博客后台编辑器中输入下面的URL: http://www.windowsphone.com/zh-cn/store/app/博客园-uap/500f08f0-5 ...
- Nodejs进阶:如何玩转子进程(child_process)
本文摘录自个人总结<Nodejs学习笔记>,更多章节及更新,请访问 github主页地址.欢迎加群交流,群号 197339705. 模块概览 在node中,child_process这个模 ...
- web安全——目录
说明 写这个目录是为了方便阅读.也是为了记录统一的问题. 这个系列,并不一定是全的,也不一定是对的,所以请大家多做过滤. 这里面场景比较多的是本人在实践中遇到的问题,然后自己思考抽象的. 目录 web ...
- (十)装饰器模式详解(与IO不解的情缘)
作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. LZ到目前已经写了九个设计模 ...
- BroadcastReceiver之有序广播
有序广播可以按一定的优先级进行传播 首先进行发送广播 public void click(View v){ Intent intent = new Intent(); intent.setAction ...
- 解决"415 Cannot process the message because the content type 'application/x-www-form-urlencoded' was not the expected type 'text/xml; charset=utf-8'"
wcf basicHttpBinding content-type text/xml;charset=utf-8 wsHttpBinding 'application/soap+xml; ch ...
- python基础-range用法_python2.x和3.x的区别
#range帮助创建连续的数字,通过设置步长来指定不连续 python2.7 #直接就在内存中创建出来(0-99) >>> range(100)[0, 1, 2, 3, 4, 5, ...
- 软件工程(FZU2015)增补作业
说明 张老师为FZU软件工程2015班级添加了一次增补作业,总分10分,deadline是2016/01/01-2016/01/03 前11次正式作业和练习的迭代评分见:http://www.cnbl ...