鉴于这种:
public enum States implements StateEnum {
SHOWING_WELCOME,
WAITING_FOR_PIN,
CHECKING_PIN,
RETURNING_CARD,
SHOWING_MAIN_MENU,
SHOWING_PIN_INVALID,
SHOWING_CARD_LOCKED,
SHOWING_BALANCE,
SHOWING_WITHDRAW_MENU,
SHOWING_TAKE_CASH,
TERMINATED
}
public enum Events implements EventEnum {
cardPresent,
cardExtracted,
pinProvided,
pinValid,
pinInvalid,
tryAgain,
noMoreTries,
cancel,
confirm,
menuShowBalance,
menuWithdrawCash,
menuExit,
switchOff,
cashExtracted
}
我想知道是否有一种方法可以创建一种算法来自动执行此操作:
from(SHOWING_WELCOME).transit(
on(cardPresent).to(WAITING_FOR_PIN).transit(
on(pinProvided).to(CHECKING_PIN).transit(
on(pinValid).to(SHOWING_MAIN_MENU).transit(
on(menuShowBalance).to(SHOWING_BALANCE).transit(
on(cancel).to(SHOWING_MAIN_MENU)
),
on(menuWithdrawCash).to(SHOWING_WITHDRAW_MENU).transit(
on(cancel).to(SHOWING_MAIN_MENU),
on(confirm).to(SHOWING_TAKE_CASH).transit(
on(cashExtracted).to(SHOWING_MAIN_MENU)
)
),
on(menuExit).to(RETURNING_CARD)
),
on(pinInvalid).to(SHOWING_PIN_INVALID).transit(
on(tryAgain).to(WAITING_FOR_PIN),
on(noMoreTries).to(SHOWING_CARD_LOCKED).transit(
on(confirm).to(SHOWING_WELCOME)
),
on(cancel).to(RETURNING_CARD)
)
),
on(cancel).to(RETURNING_CARD).transit(
on(cardExtracted).to(SHOWING_WELCOME)
)
),
on(switchOff).finish(TERMINATED)
);
我正在考虑创建两个列表(事件和状态)以这种方式使用这些值:
on(Events.valueOf(EventsList.get(0))).to(States.valueOf(EventsList.get(0)).trans it(
...
但是,我不确定哪个是迭代的模式。
我真的很感激任何建议。
谢谢
//////////////////////////// 更新///////////////////// //////////////
基于@Dukeling 建议的解决方案
public Map<States, List<Events>> transitMap;
public Map<Events, States> toMap;
void transitCaller(States initialState, Events events)
{
transitCallerHelper(on(events).to(initialState),
transitMap.get(initialState));
}
Transition transitCallerHelper(Transition toResult, List<Events> events)
{
List<Transition> transitCalls = new ArrayList<Transition>();
for (Events e: events)
{
States s = toMap.get(e);
if (isFinishEvent(e)) // or isFinishState(s)
transitCalls.add(on(e).finish(s));
else
{
events = (s != null ? transitMap.get(s) : null);
if (events == null)
transitCalls.add(on(e).to(s));
else
transitCalls.add(transitCallerHelper(on(e).to(s), events));
}
}
return toResult.transit(transitCalls.get(0));
}