:https://google-styleguide.googlecode.com/svn/trunk/javaguide.html#s4.8.4.3-switch-default
package com.enumTest.enumStateMac;
import java.util.Arrays;
import java.util.Random;
public enum Input {
NICKEL(5), DIME(10), QUARTER(25), DOLLAR(100), TOOTHPASTE(200), CHIPS(75), SODA(100), SOAP(50),
ABORT_TRANSACTION {
public int amout() {
throw new RuntimeException("ABORT.amout()");
}
},
STOP {
// last instance
public int amout() {
throw new RuntimeException("SHUT.amout()");
}
};
// 商品价格
int value;
Input(int value) {
this.value = value;
}
Input() {
}
int amount() {
return value;
}
static Random rand = new Random(47);
public static Input randomSelection() {
// Dont include STOP:
return values()[rand.nextInt(values().length - 1)];
}
public static void main(String[] args) {
}
}
package com.enumTest.enumStateMac;
import static net.mindview.util.Print.*;
import java.util.EnumMap;
import java.util.Iterator;
import java.util.logging.Logger;
import net.mindview.util.TextFile;
import com.java.array.generator.Generator;
enum Category {
// 定义 Category enum实例
MONEY(Input.NICKEL, Input.DIME, Input.QUARTER, Input.DOLLAR),
ITEM_SELECTION(Input.TOOTHPASTE, Input.CHIPS, Input.SODA, Input.SOAP),
QUIT_TRANSACTION(Input.ABORT_TRANSACTION),
SHUT_DOWN(Input.STOP);
// 初始化 Input 实例
private Input[] values;
Category(Input... types) {
values = types;
}
private static EnumMap<Input, Category> categories = new EnumMap<Input, Category>(Input.class);
// 填充categories <输入内容 ,根据输入得到的相应菜单>
static {
for (Category c : Category.class.getEnumConstants())
for (Input type : c.values)
categories.put(type, c);
}
// 根据输入获取 相应的类别菜单
public static Category categorize(Input input) {
return categories.get(input);
}
}
public class VendingMachine {
// 默认机器 state 为 休息状态
private static State state = State.RESTING;
// 默认机器 amount =0 投币金额
private static int amount = 0;
private static Input selection = null;
enum StateDuration {
TRANSIENT
} // Tagging enum
// 机器的状态 枚举实例如下:
// 待机状态 投币状态 出货状态 找零状态 中断操作状态
enum State {
// 按照输入内容 进行不同反应
// 待机状态 将执行:
RESTING {
void next(Input input) {
try {
System.out.println("now State: " + state + " RESTING : input: " + input);
Thread.sleep(10000l);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
switch (Category.categorize(input)) {
// 如果输入是金额 1.投币金额设置 2.机器状态设置为 投币
case MONEY:
amount += input.amount();
state = ADDING_MONEY;
break;// break to where
// 如果是 关机
case SHUT_DOWN:
state = TERMINAL;
// why ???
default:
}
}
},
// 如果机器是投币状态 将执行:
ADDING_MONEY {
void next(Input input) {
try {
System.out.println("now State: " + state + " ADDING_MONEY : input: " + input);
Thread.sleep(5000l);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
switch (Category.categorize(input)) {
// 继续投币 操作
case MONEY:
amount += input.amount();
break;
// 选择物品 操作
case ITEM_SELECTION:
selection = input;
// 金额不足
if (amount < selection.amount())
print("Insufficient money for " + selection);
else
// 出货状态
state = DISPENSING;
break;
// 取消操作
case QUIT_TRANSACTION:
// 找零
state = GIVING_CHANGE;
break;
// 关闭
case SHUT_DOWN:
state = TERMINAL;
default:
}
}
},
// 出货
DISPENSING(StateDuration.TRANSIENT) {
void next() {
try {
System.out.println("now State: " + state + " DISPENSING : input: ");
Thread.sleep(5000l);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 出货,扣费,置为找零状态
print("here is your " + selection);
amount -= selection.amount();
state = GIVING_CHANGE;
}
},
GIVING_CHANGE(StateDuration.TRANSIENT) {
void next() {
try {
System.out.println("now State: " + state + " GIVING_CHANGE : input: ");
Thread.sleep(5000l);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 找零 置为待机
if (amount > 0) {
print("Your change: " + amount);
amount = 0;
}
state = RESTING;
}
},
TERMINAL {
void output() {
print("Halted");
}
};
private boolean isTransient = false;
State() {
}
State(StateDuration trans) {
isTransient = true;
}
// 操作状态 :待机状态 投币状态 此方法必须重写
void next(Input input) {
throw new RuntimeException("Only call " + "next(Input input) for non-transient states");
}
// 在机器非自动运转状态:出货状态 找零状态 此方法必须重写
void next() {
throw new RuntimeException("Only call next() for " + "StateDuration.TRANSIENT states");
}
void output() {
print("over amount : " + amount);
}
}
// 售货机 静态方法
static void run(Generator<Input> gen) {
while (state != State.TERMINAL) {
Input inputTemp = gen.next();
if (null == inputTemp/* 限制性 返回Input 中的一个操作 */) {
return;
}
state.next(inputTemp/* 限制性 返回Input 中的一个操作 */);// 返回输入的Input操作的
// 相应
// 如果上一步操作是 待机状态 投币状态 也就是说会有=下一步操作的 操作(会调用 next(para),transient
// 置为true)。
while (state.isTransient)
// state.isTransient 代表有下一步 操作
state.next();
state.output();
}
}
public static void main(String[] args) {
// 获得一个 Input
Generator<Input> gen = new RandomInputGenerator();
if (args.length == 1)
// 输入操作命令 完成命令 初始化
gen = new FileInputGenerator(args[0]);
run(gen);
}
}
// For a basic sanity check:
class RandomInputGenerator implements Generator<Input> {
public Input next() {
return Input.randomSelection();
}
}
// Create Inputs from a file of ‘;’-separated strings:
class FileInputGenerator implements Generator<Input> {
private Iterator<String> input;
public FileInputGenerator(String fileName) {
input = new TextFile(fileName, ";").iterator();
}
// 限制性 返回Input 中的一个操作
public Input next() {
if (!input.hasNext())
return null;
String inputNext = input.next().trim();
if (inputNext == null || "".equals(inputNext)) {
System.out.println("指令不合法");
return Input.ABORT_TRANSACTION;
}
Input inputGenerated = Enum.valueOf(Input.class, inputNext);
System.out.println(inputGenerated);
return inputGenerated;
}
}
package com.java.array.generator;
public interface Generator<T> {
T next();
}
//: net/mindview/util/TextFile.java
package net.mindview.util;
import java.io.*;
import java.util.*;
public class TextFile extends ArrayList<String> {
// Read a file as a single string:
public static String read(String fileName) {
StringBuilder sb = new StringBuilder();
try {
BufferedReader in= new BufferedReader(new FileReader(
new File(fileName).getAbsoluteFile()));
try {
String s;
while((s = in.readLine()) != null) {
sb.append(s);
sb.append("\n");
}
} finally {
in.close();
}
} catch(IOException e) {
throw new RuntimeException(e);
}
return sb.toString();
}
// Read a file, split by any regular expression:
public TextFile(String fileName, String splitter) {
super(Arrays.asList(read(fileName).split(splitter)));
// Regular expression split() often leaves an empty
// String at the first position:
if(get(0).equals("")) remove(0);
}
// Normally read by lines:
public TextFile(String fileName) {
this(fileName, "\n");
}
}