【问题标题】:State machine default event handling状态机默认事件处理
【发布时间】:2016-01-16 10:12:30
【问题描述】:

考虑这个我想用作状态机的枚举:

public enum PositionFSM {

  State1 {
    @Override
    PositionFSM processFoo() {
      return State2;
    }
  },
  State2 {
    @Override
    PositionFSM processFoo() {
      return State1;
    }
  };

  abstract PositionFSM processFoo();

  abstract PositionFSM processBar();

  PositionFSM processBar() {
    return this;
  }
}

我们的目标是避免所有个状态必须实现它们除了返回当前状态之外什么都不做的所有事件。

在此示例中,processBar 的调用应被 State1State2 忽略。

我指的是answer,但给出的枚举不会编译(Java 1.8)。 有没有办法按照我想要的方式去做?

【问题讨论】:

    标签: java enums state-machine


    【解决方案1】:

    只需评论该行

    abstract PositionFSM processBar();
    

    因为无论如何你已经在你的枚举类中给出了实现。

      PositionFSM processBar() {
        return this;
      }
    

    然后你可以访问你的枚举的两种方法,如下所示

    PositionFSM.State1.processFoo(); //valid no syntax error
    PositionFSM.State1.processBar();
    

    如果需要,您可以覆盖任何常量的 processBar 方法,如下所示

      State2 {
        @Override
        PositionFSM processFoo() {
          return State1;
        }
    
        @Override
        PositionFSM processBar(){
            return this;
        }
      };
    

    【讨论】:

      【解决方案2】:

      您需要先定义枚举变量,然后是方法(我不知道为什么链接的答案会反过来,这在 java 中从未起作用)。另外不要让方法抽象,所以你可以提供一个默认的实现:

      public enum State
      {
          State1
          {
              @Override
              public State process()
              {
                  return State2;
              }
          },
          State2,
          State3;
      
          public State process()
          {
              return this;
          }
      }
      

      测试它:

      System.out.println(State.State1.process());
      System.out.println(State.State2.process());
      System.out.println(State.State3.process());
      

      产生以下输出:

      State2
      State2
      State3
      

      【讨论】:

        【解决方案3】:

        此代码无法编译,因为 processBar() 被声明了两次。只需删除该行

        abstract PositionFSM processBar();
        

        代码将被编译。

        【讨论】:

        • 似乎合乎逻辑,我想知道为什么推荐的示例答案有这么多的赞成票,尽管它不起作用。
        【解决方案4】:

        这个确实编译:

        ublic enum PositionFSM {
        
          State1 {
            @Override
            PositionFSM processFoo() {
              return State2;
            }
          },
          State2 {
            @Override
            PositionFSM processFoo() {
              return State1;
            }
          };
        
          abstract PositionFSM processFoo();
        
          PositionFSM processBar() {
            return this;
          }
        }
        

        processBar() 方法被声明了两次。


        编辑>

        Java 8 的替代方法可能是使用带有 默认方法的接口,如下所示:

        public interface IPositionFSM {
        
            default IPositionFSM processFoo() {
                return this;
            }
        
            default IPositionFSM processBar() {
                return this;
            }
        }
        
        public enum PositionFSM implements IPositionFSM {
            State1 {
                @Override
                public IPositionFSM processFoo() {
                    return State2;
                }
            },
            State2 {
                @Override
                public IPositionFSM processBar() {
                    return State1;
                }
            };
        }
        

        【讨论】:

          猜你喜欢
          • 2013-03-17
          • 2011-08-12
          • 2021-12-15
          • 1970-01-01
          • 2013-03-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多