先是输入的枚举类型

public enum Input {
NICKEL(5), DIME(10), QUARTER(25), DOLLAR(100),
TOOTHPASTE(200), CHIPS(75), SODA(100), SOAP(50),
ABORT_TRANSACTION {
public int amount() { // Disallow
throw new RuntimeException("ABORT.amount()");
}
},
STOP { // This must be the last instance.
public int amount() { // Disallow
throw new RuntimeException("SHUT_DOWN.amount()");
}
};
int value; // In cents
Input(int value) { this.value = value; }
Input() {}
int amount() { return value; }; // In cents
static Random rand = new Random(47);
public static Input randomSelection() {
// Don't include STOP:
return values()[rand.nextInt(values().length - 1)];
}
}

分析里面的values都是NICKEL(5), DIME(10), QUARTER(25), DOLLAR(100),
TOOTHPASTE(200), CHIPS(75), SODA(100), SOAP(50)
代表的钱的面值和商品的价格
randomSelection()方法随机输出一个values数组中的值除了STOP;

enum Category {
MONEY(NICKEL, DIME, QUARTER, DOLLAR),
ITEM_SELECTION(TOOTHPASTE, CHIPS, SODA, SOAP),
QUIT_TRANSACTION(ABORT_TRANSACTION),
SHUT_DOWN(STOP);
//Input.values
private Input[] values;
Category(Input... types) { values = types; }
private static EnumMap<Input,Category> categories =
new EnumMap<Input,Category>(Input.class);
//将enum赋值给c 将Input 和c加入EnumMap
static {
for(Category c : Category.class.getEnumConstants())
for(Input type : c.values)
categories.put(type, c);
}
//返回c.values的值
public static Category categorize(Input input) {
return categories.get(input);
}
}

public class VendingMachine {
//state是状态
private static State state = State.RESTING;
//加入自动贩卖机的钱
private static int amount = 0;
private static Input selection = null;
enum StateDuration { TRANSIENT } // Tagging enum
enum State {
//初始状态
RESTING {
void next(Input input) {
switch(Category.categorize(input)) {
case MONEY:
amount += input.amount();
print("amount"+amount);
state = ADDING_MONEY;
break;
case SHUT_DOWN:
state = TERMINAL;
default:
}
}
},
//价钱到贩卖机
ADDING_MONEY {
void next(Input input) {
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() {
print("here is your " + selection);
amount -= selection.amount();
state = GIVING_CHANGE;
}
},
//找钱
GIVING_CHANGE(StateDuration.TRANSIENT) {
void next() {
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(amount); }
}
static void run(Generator<Input> gen) {
while(state != State.TERMINAL) {
state.next(gen.next());
while(state.isTransient)
state.next();
state.output();
}
}
public static void main(String[] args) {
Generator<Input> gen = new RandomInputGenerator();
//判断从哪里输入
if(args.length == 1)
gen = new FileInputGenerator(args[0]);
运行
run(gen);
}
}

//输入Input
class RandomInputGenerator implements Generator<Input> {
public Input next() { return Input.randomSelection(); }
}

//文件输入
class FileInputGenerator implements Generator<Input> {
private Iterator<String> input;
public FileInputGenerator(String fileName) {
input = new TextFile(fileName, ";").iterator();
}
public Input next() {
if(!input.hasNext())
return null;
return Enum.valueOf(Input.class, input.next().trim());
}
}

在看程序执行的过程RandomInputGenerator或者FileInputGenerator输入Input,
判断从哪里输入 执行run。
run方法,判断是否为Transient。若为Transient,异常,输出剩余的amount(钱)
新手:欢迎指正

更多相关文章

  1. 字体图标的引入和通过媒体查询改变导航样式
  2. HTML样式和常用选择器
  3. 字体图标的引用和自定义样式/媒体查询的使用
  4. 数据库的CURD操作、PDO本质与原理的学习
  5. CSS之伪类选择器和简单盒子简单案例
  6. 伪类选择器与盒模型常用属性
  7. 伪类选择器-结构伪类、根据位置选择匹配
  8. 7.4——常用标签与应用场景之表格与单元格
  9. css伪类选择器和盒模型

随机推荐

  1. Android从零开搞系列:自定义View(15)仿天天
  2. 【Android】策略模式封装百度地图路线规
  3. JustWe-WebServer Android上的Http服务器
  4. DialogFragment自定义dialog的位置和大小
  5. Android进阶系列4—从LayoutInflater到se
  6. Unity Android使用相机拍摄照片并在其上
  7. Android开发如何验证输入的手机号码是否
  8. opencv实时视频帧在android中没有显示sob
  9. 通过数据库接口获取到的中文数据是问号怎
  10. 尽管在清单文件中指定了权限,但是ACCESS_F