Input
package com.enumState;
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
{
;
@Override
int amount()
{
throw new RuntimeException("ABORT.amount()");
}
},
STOP
{
@Override
int amount()
{
throw new RuntimeException("SHUT_DOWN.amount()");
}
};
int value;
Input()
{
}
Input(int value)
{
this.value = value;
}
int amount()
{
return value;
}
static Random random = new Random(47);
public static Input randonSelection()
{
// Don't include STOP
return values()[random.nextInt(values().length - 1)];
}
}
Generator
package com.enumState;
public interface Generator<T>
{
T next();
}
VendingMachine
package com.enumState;
import static com.enumState.Input.ABORT_TRANSACTION;
import static com.enumState.Input.CHIPS;
import static com.enumState.Input.DIME;
import static com.enumState.Input.DOLLAR;
import static com.enumState.Input.NICKEL;
import static com.enumState.Input.QUARTER;
import static com.enumState.Input.SOAP;
import static com.enumState.Input.SODA;
import static com.enumState.Input.STOP;
import static com.enumState.Input.TOOTHPASTE;
import java.util.EnumMap;
enum Category
{
MONEY(NICKEL, DIME, QUARTER, DOLLAR),
ITEM_SELECTION(TOOTHPASTE, CHIPS, SODA, SOAP),
/**
* 退出交易
*/
QUIT_TRANSACTION(ABORT_TRANSACTION),
SHUT_DOWN(STOP);
private Input[] values;
Category(Input... types)
{
this.values = types;
}
private static EnumMap<Input, Category> categories = new EnumMap<Input, Category>(Input.class);
static
{
for (Category c : Category.class.getEnumConstants())
{
for (Input type : c.values)
{
categories.put(type, c);
}
}
System.out.println("categories : "+categories);
}
// 获取相应type的值
public static Category categorize(Input type)
{
return categories.get(type);
}
}
public class VendingMachine
{
private static State state = State.RESTING;
private static int amount = 0;
private static Input selection = null;
enum StateDuration
{
TRANSIENT
};// Tagging enum
enum State
{
/**
* 休息
*/
RESTING
{
@Override
void next(Input input)
{
switch (Category.categorize(input))
{
case MONEY:
amount += input.amount();
state = ADDING_MONEY;
break;
case SHUT_DOWN:
state = TERMINAL;
default:
}
}
},
ADDING_MONEY
{
@Override
void next(Input input)
{
switch (Category.categorize(input))
{
case MONEY:
amount += input.amount();
state = ADDING_MONEY;
break;
case ITEM_SELECTION:
selection = input;
if (amount < input.amount())
System.out.println("Your money is not enough. ");
else
state = DISPENSING;
break;
case QUIT_TRANSACTION:
state = GIVING_CHANGE;
break;
case SHUT_DOWN:
state = TERMINAL;
default:
}
}
},
/**
* 配送
*/
DISPENSING(StateDuration.TRANSIENT)
{
@Override
void next()
{
System.out.println("here is your " + selection);
amount-=selection.amount();
state=GIVING_CHANGE;
}
},
/**
* 进行更改
*/
GIVING_CHANGE(StateDuration.TRANSIENT)
{
@Override
void next()
{
if (amount > 0)
{
System.out.println("Your change : " + amount);
amount = 0;
}
state = RESTING;
}
},
/**
* 终点
*/
TERMINAL
{
@Override
void output()
{
System.out.println("Halted");
}
};
private boolean isTransient = false;
State()
{
};
State(StateDuration trans)
{
isTransient = true;
};
void next(Input input)
{
throw new RuntimeException("input od next find exception");
}
void next()
{
throw new RuntimeException("next find exception");
}
void output()
{
System.out.println(amount);
}
}
//
static void run(Generator<Input> gen)
{
while (state != State.TERMINAL)
{
Input next = gen.next();
state.next(next);
while (state.isTransient)
{
state.next();
}
state.output();
}
}
// test
public static void main(String[] args)
{
Generator<Input> gen = new RandomGenerator();
run(gen);
}
} // 随机生成
class RandomGenerator implements Generator<Input>
{
@Override
public Input next()
{
return Input.randonSelection();
}
}