【问题标题】:Java loop algorithmJava循环算法
【发布时间】:2017-03-28 22:12:27
【问题描述】:

鉴于此:

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

}

【问题讨论】:

    标签: java algorithm loops automation automaton


    【解决方案1】:

    我最初的想法是使用映射来定义您的 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 设为单数而不是复数,因为枚举中的每个值仅分别定义一个状态和事件。

    【讨论】:

    • 感谢您的宝贵回答,对不起,我有一个问题:“from”有不同类型的“on”和finish,它们都是“Transaction”,因为我们需要使用递归方法,它应该失败了不是吗?我正在尝试申请此代码:pastebin.com/fewi8R0F(演示)为此库:github.com/Beh01der/EasyFlow。谢谢。我做了修改,但它不起作用,请查看修改/扩展问题。
    • @user1069571 但它也有transit 方法?在这种情况下,您可能希望将该方法放在您在两个类中实现的interface 中。然后,您可以在递归方法中使用此接口代替ReturnType,因为拥有transit 方法是递归方法唯一关心的事情。或者,您可以将大部分 transitCallerHelper 方法原样移动到另一个返回 List&lt;ReturnType&gt; 的方法 (getTransitArgs),然后在 transitCaller 中执行 from(initialState).transit(getTransitArgs(transitMap.get(initialState)));
    • toResult.transit(transitCalls.get(0)); 将不起作用 - 始终调用 transit 时只有我们列表中的一个项目(get(0) 获取第一个元素)。只需使用transitCalls.toArray(new Transaction[0]) 将其转换为数组即可。
    • 对不起,有两件事: 1. : 这样做:from(initialState).transit(getTransitArgs(transitMap.get(ini‌​tialState))),它返回一个事件列表,但是 getTransitArgs(州 initialState) 需要您知道的州。 2. 抱歉,我不清楚 getTransitArgs 函数会返回 List 吗?谢谢,非常感谢
    • 1.我不确定你指的是什么。我没有看到代码有问题 - 我们可以访问我们需要的所有信息。 2. 由于transit 将数组作为参数(不是List),因此返回Transition[] 更简单。 toArray 函数返回一个数组。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-19
    • 1970-01-01
    • 2011-09-17
    • 2011-03-10
    • 2011-05-27
    • 1970-01-01
    相关资源
    最近更新 更多