java编程思想恶心的enum状态机示例
下面是一个包装输入的类
package test; import java.util.Random; public enum Input {
NICKEL(5) , DIME(10) , QUARTER(25),DOLLAR(100),
TOOTHPASTE(200),CHIPS(75),SODA(100),SOAP(50),
ABOUT_TRANSACTION{
@Override
int amount() {
throw new RuntimeException("ABOUT_TRANSACTION") ;
}
} ,
STOP {
@Override
int amount() {
throw new RuntimeException("SHUT_DOWN.amount()") ;
}
} ; private int value ;
private Input(){}
private Input(int value ){
this.value = value ;
}
int amount(){
return value ;
}
/**
* 随机生成输入
*/
static Random random = new Random() ;
public static Input randomSelection(){
/**
* 产生 0 ~ values().length区间内的数 , 包括0 不包括values().length
*/
return values()[random.nextInt(values().length )] ;
}
public static void main(String[] args) {
for(int i = 0 ; i < 10 ; i ++){
System.out.println(Input.randomSelection());
}
}
}
在书中(第四版)values()[random.nextInt(values().length)]写错了,后面多减了一个1,
下面是主类,真不知道作者天天在想什么,竟然能想出这样的设计 --!
package test;
import static test.Input.ABOUT_TRANSACTION;
import static test.Input.CHIPS;
import static test.Input.DIME;
import static test.Input.DOLLAR;
import static test.Input.NICKEL;
import static test.Input.QUARTER;
import static test.Input.SOAP;
import static test.Input.SODA;
import static test.Input.STOP;
import static test.Input.TOOTHPASTE; import java.util.EnumMap;
/**
*
* 状态转换
*
* 模拟自动售货机的运行
*
*/ /**
* 该类是为了获得输入命令的类别
*/
enum Category{
MONEY(NICKEL,DIME,QUARTER,DOLLAR),
ITEM_SELECTION(TOOTHPASTE,CHIPS,SODA,SOAP),
QUIT_TRANSACTION(ABOUT_TRANSACTION),
SHUT_DOWN(STOP) ;
private Input[] values ;
private Category(Input... inputs ){
values = inputs ;
}
private static EnumMap<Input,Category> categories = new EnumMap<Input,Category>(Input.class) ; static {
for( Category c : Category.class.getEnumConstants()){
for( Input i : c.values){
categories.put(i, c) ;
}
}
}
public static Category getCategory(Input input ){
return categories.get(input) ;
}
}
public class VendingMachine {
/**
* 模拟状态之间的转换
*
*/
private static int amount = 0 ;
private static State state = State.RESTING ;
private static Input selection = null ;
enum StateDuration {TRANSIENT}
enum State {
RESTING {
void next(Input input ){
switch(Category.getCategory(input)){
case MONEY :
amount += input.amount() ;
state = ADDING_MONEY ;
break ;
case SHUT_DOWN:
state = TERMINAL ;
break ;
default :
}
}
},
ADDING_MONEY {
void next(Input input ){
switch(Category.getCategory(input)){
case MONEY :
amount += input.amount() ;
/**
* 这里为什么不要设置state的值?
* 因为当前已经是ADDING_MONEY状态,设置了以后还是这个状态,所以不需要设置
*/
break ;
case ITEM_SELECTION :
selection = input ;
if(amount < input.amount()){
System.out.println("Insufficient money for " + selection );
}else{
state = DISPENSING ;
}
break ;
case QUIT_TRANSACTION :
state = GIVING_CHANGE ;
break ;
case SHUT_DOWN :
state = TERMINAL ;
break ;
default :
}
}
},
DISPENSING(StateDuration.TRANSIENT){
void next(){
System.out.println("Here is your " + selection ) ;
amount -= selection.amount() ;
state = GIVING_CHANGE ;
}
},
GIVING_CHANGE(StateDuration.TRANSIENT){
void next(){
if(amount > 0 ){
System.out.println("you change : " + amount ) ;
amount = 0 ;
}
state = RESTING ;
}
},
TERMINAL {
void output(){
System.out.println("Halted!");
}
} ;
private boolean isTransaction = false ;
void next(){ }
void next(Input input ){
throw new RuntimeException("Only call next(Input input) for non-transient states ") ;
}
void output(){System.out.println(amount);}
State(){}
State(StateDuration trans ){
this.isTransaction = true ;
}
}
public static void run(Generator<Input> gen ){
/**
* 如果在前面执行的命令中是state变为terminal,则程序结束。
* 让其变为terminal的情况为输入的命令为STOP即SHUT_DOWN类别
*/
while(state != State.TERMINAL ){
/**
* 输入随机产生命令 , 当输入的命令非transaction类型的命令时,抛出异常 ,这在默认的next中设定
* 这里的state不可能是TERMINAL,也不可能是Transaction(因为下面那个while无限循环),
* 所以永远不会执行那个会抛出异常的next方法。
*/
state.next(gen.next()) ;
/**
* 判断该命令的剩下执行是否还需要命令,Transaction是true表示下面将要执行的任务不需要再输入命令
* 所以使用无限循环将该命令执行完,然后再输出余额
*/
while(state.isTransaction){
state.next() ;
}
state.output() ;
}
}
public static void main(String[] args) {
Generator<Input> gen = new RandomInputGenerator() ;
run(gen) ;
}
}
class RandomInputGenerator implements Generator<Input>{
@Override
public Input next() {
return Input.randomSelection() ;
}
}
java编程思想恶心的enum状态机示例的更多相关文章
- Java编程思想 (1~10)
[注:此博客旨在从<Java编程思想>这本书的目录结构上来检验自己的Java基础知识,只为笔记之用] 第一章 对象导论 1.万物皆对象2.程序就是对象的集合3.每个对象都是由其它对象所构成 ...
- Java编程思想 第21章 并发
这是在2013年的笔记整理.现在重新拿出来,放在网上,重新总结下. 两种基本的线程实现方式 以及中断 package thread; /** * * @author zjf * @create_tim ...
- 《Java编程思想》读书笔记(三)
前言:三年之前就买了<Java编程思想>这本书,但是到现在为止都还没有好好看过这本书,这次希望能够坚持通读完整本书并整理好自己的读书笔记,上一篇文章是记录的第十一章到第十六章的内容,这一次 ...
- 《Java编程思想》读书笔记(四)
前言:三年之前就买了<Java编程思想>这本书,但是到现在为止都还没有好好看过这本书,这次希望能够坚持通读完整本书并整理好自己的读书笔记,上一篇文章是记录的第十七章到第十八章的内容,这一次 ...
- 《Java编程思想》读书笔记(五)
前言:本文是<Java编程思想>读书笔记系列的最后一章,本章的内容很多,需要细读慢慢去理解,文中的示例最好在自己电脑上多运行几次,相关示例完整代码放在码云上了,码云地址:https://g ...
- JAVA编程思想(第四版)学习笔记----4.8 switch(知识点已更新)
switch语句和if-else语句不同,switch语句可以有多个可能的执行路径.在第四版java编程思想介绍switch语句的语法格式时写到: switch (integral-selector) ...
- 《Java编程思想》读书笔记
前言 这个月一直没更新,就是一直在读这本<Java编程思想>,这本书可以在Java业界被传神的一本书,无论谁谈起这本书都说好,不管这个人是否真的读过这本书,都说啊,这本书很好.然后再看这边 ...
- 《Java编程思想第四版完整中文高清版.pdf》-笔记
D.2.1 安插自己的测试代码 插入下述“显式”计时代码,对程序进行评测: long start = System.currentTimeMillis(); // 要计时的运算代码放在这儿 long ...
- Java编程思想 4th 第2章 一切都是对象
Java是基于C++的,但Java是一种更纯粹的面向对象程序设计语言,和C++不同的是,Java只支持面向对象编程,因此Java的编程风格也是纯OOP风格的,即一切都是类,所有事情通过类对象协作来完成 ...
随机推荐
- HDU 4858 项目管理 分块
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4858 题解: 下面说一个插入查询时间复杂度为sqrt(m)的算法: 对每个点定义两个值:val,su ...
- POJ 3349 HASH
题目链接:http://poj.org/problem?id=3349 题意:你可能听说话世界上没有两片相同的雪花,我们定义一个雪花有6个瓣,如果存在有2个雪花相同[雪花是环形的,所以相同可以是旋转过 ...
- 制作一个访问量很高的大型网站,你会如何来管理所有HTML、CSS、JS与图片?
1.先确定全局样式和编码方式. 2.编写习惯,标注样式. 3.文件夹存放,命名.
- 移动开单扫描终端-全触屏互联网安卓打印扫描 PDAPOS机——开单扫描POS-移动开单扫描POS
浩瀚云POS是一款自主研发的全触屏互联网POS,一贯以领先的技术.快捷友好的用户体验和在全国广泛覆盖的网络,为电子商务.提供安全.可靠.保密的数据校验服务.作为其研发的一款专业移动开单扫描终端. 互联 ...
- 泛型容器单元(Generics.Collections)[3]: TStack<T> 堆栈列表
TQueue 和 TStack, 一个是队列列表, 一个是堆栈列表; 一个是先进先出, 一个是先进后出. TStack 主要有三个方法.一个属性:Push(压栈).Pop(出栈).Peek(查看下一个 ...
- SOLID面向对象的五个设计原则,留空待学习。
SOLID面向对象的五个设计原则对于开发人员非常重要,其身影在任何大中型软件项目中随处可见,建议必须掌握并灵活应用.此五原则分别为: 单一职责原则(Single Resposibility ...
- spring-boot项目在外部tomcat环境下部署
http://m.blog.csdn.net/article/details?id=51009423
- Java线程并发控制基础知识
微博上众神推荐今年4月刚刚出版的一本书,淘宝华黎撰写的<大型网站系统与Java中间件实践>,一线工程师的作品,实践出真知,果断要看. 前两章与<淘宝技术这十年>内容类似,基本是 ...
- start bbs轻论坛安装时数据库提示错误
A PHP Error was encounteredSeverity: NoticeMessage: Only variable references should be returned by r ...
- Optimizing Performance: Data Binding(zz)
Optimizing Performance: Data Binding .NET Framework 4.5 Other Versions Windows Presentation Founda ...