鉴于此:
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));
}
我最初的想法是用映射来定义您的transit
和to
映射:
Map<States, List<Events>> transitMap;
Map<Events, States> toMap;
您可以将这些映射存储在文本文件中,从中可以构建上述映射。
从这里你可以创建一个递归方法来调用你的方法:
(这有点混乱,因为from
返回不同的类型(
void transitCaller(State initialState)
{
from(initialState).transit(getTransitArgs(transitMap.get(initialState)));
}
Transition transitCallerHelper(Transition toResult, List<Events> events)
{
return toResult.transit(getTransitArgs(events));
}
Transition[] getTransitArgs(List<Events> events)
{
List<Transition> transitArgs = new ArrayList<Transition>();
for (Events e: events)
{
States s = toMap.get(e);
if (isFinishEvent(e)) // or isFinishState(s)
transitArgs.add(on(e).finish(s));
else
{
List<Events> events = (s != null ? transitMap.get(s) : null);
if (events == null)
transitArgs.add(on(e).to(s));
else
transitArgs.add(transitCallerHelper(on(e).to(s), events));
}
}
return transitArgs.toArray(new Transaction[0]);
}
(根据需要添加错误检查(
旁注:您可能希望将States
和Events
设置为单数而不是复数,因为枚举中的每个值分别只定义单个状态和事件。