Java 循环算法



鉴于此:

 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));

}

我最初的想法是用映射来定义您的transitto映射:

Map<States, List<Events>> transitMap;
Map<Events, States> toMap;

您可以将这些映射存储在文本文件中,从中可以构建上述映射。

从这里你可以创建一个递归方法来调用你的方法:
(这有点混乱,因为from返回不同的类型(

void transitCaller(State initialState)
{
   from(initialState).transit(getTransitArgs(transitMap.get(ini‌​tialState)));
}
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]);
}

(根据需要添加错误检查(


旁注:您可能希望将StatesEvents设置为单数而不是复数,因为枚举中的每个值分别只定义单个状态和事件。

最新更新