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风格的,即一切都是类,所有事情通过类对象协作来完成 ...
随机推荐
- js高级技巧之高级定时器
实际上,浏览器负责进行排序,指派某段代码在某个时间点运行的优先级. 可以吧js想象成在时间线上运行的. JavaScript中没有任何代码是立刻执行的,但一旦进程空闲则尽快执行. 1.重复的定时器: ...
- Spring事务解析3-增强方法的获取
从InfrastructureAdvisorAutoProxyCreator的层次结构中可以看到,InfrastructureAdvisorAutoProxyCreator间接实现了SmartInst ...
- coffeeScript学习01
安装 这里使用node.js npm install -g coffee-script # watch and compile coffee -w --output lib --compile src ...
- js简版图片左右切换功能
function leftMove(obj,direction,lis){ var num = 0; var liWidth = lis[0].offsetWidth; setInterval(fun ...
- (转)解决:本地计算机 上的 OracleOraDb10g_home1TNSListener服务启动后停止
原文地址:http://justsee.iteye.com/blog/1320059 手动启动一个问题:本地计算机 上的 OracleOraDb10g_home1TNSListener服务启动后停止. ...
- Shell 编程基础之 While 练习
一.语法 while [ condition ] # 当 condition 条件成立时,就进行循环,直到条件不成立停止 do #执行内容 done 二.练习 输入用户输入的参数,直到用户输入 &qu ...
- [转]error while loading shared libraries 错误解决办法总结
http://blog.csdn.net/wallwind/article/details/7580659 错误信息: error while loading shared libraries: li ...
- [Leetcode] Word BreakII
Question: Given a string s and a dictionary of words dict, add spaces in s to construct a sentence w ...
- 【BZOJ】1436: Poi2003 Trinomial
题意 \(q(1 \le q \le 10000)\)次询问,每一次求\((x^2+x+1)^n\)的第\(k\)项系数模3. 分析 听说正解是\(\binom{2n}{m} (m \% 2+1)\) ...
- HTML5中video 和 ogg
HTML5中 的ogg 从网上学习HTML5之video时看到了下面的代码,不太清楚ogg是什么,于是搜索了一些知识点供了解.