0

我想像下面那样实现 FSM

  • 第一级最基本的状态是BASE_STATE。所有状态都源自 BASE_STATE。
  • Second Level , WAITING_STATE, RUNNING_STATE, END_STATE, ... 等等(源自 BASE_STATE。没有新功能)
  • 第三级,有 2 组状态(主动和被动),对所有第二级状态进行一对一匹配,例如

ACTIVE_WAITING_STATE、ACTIVE_RUNNING_STATE、ACTIVE_END_STATE 等等 PASSIVE_WAITING_STATE、PASSIVE_RUNNING_STATE、PASSIVE_END_STATE 等等

大多数功能对于 ACTIVE 和 PASSIVE 状态都是通用的,只是覆盖了一些小功能。到这里为止没有问题。问题是,所有第三级组都有共同的功能。我的意思是,例如我必须实现 2 个不同的 increment() 函数,其中一个是 ACTIVE_xxx_STATEs,另一个是 PASSIVE_xxx_STATEs。如何在不重写所有状态的情况下做到这一点(例如 ACTIVE_WAITING_STATE 、 ACTIVE_RUNNING_STATE 、 ACTIVE_END_STATE 以及 PASSIVE 状态)

为了澄清我的问题,我丑陋的sol'n。问题是增量函数是相同的,并且为所有 ActivexxxState(以及 PassiveXXXState)重写。

public class BaseState {
    // Lots of functions
}

public class WaitingState extends BaseState{
    // Lots of functions
}

public class RunningState extends BaseState{
    // Lots of functions
}

public class EndState extends BaseState{
    // Lots of functions
}

public Class ActiveWaitingState extends WaitingState {
     // Few unique functions
     private void increment() {
         System.out.println("increment active");
     }       
}


public Class ActiveRunningState extends RunningState {
     // Few unique functions
     private void increment() {
         System.out.println("increment active");
     }       
}

public Class ActiveEndState extends EndState {
     // Few unique functions
     private void increment() {
         System.out.println("increment active");
     }       
}

public Class PassiveWaitingState extends WaitingState {
     // Few unique functions        
     private void increment() {
         System.out.println("increment passive");
     }       
}

public Class PassiveRunningState extends RunningState {

     private void increment() {
         System.out.println("increment passive");
     }       
}

public Class PassiveEndState extends EndState {

     private void increment() {
         System.out.println("increment passive");
     }       
}
4

3 回答 3

2

我会让 increment() 在 BaseState 中成为一个受保护的方法,所以它只实现一次。


我写了一篇关于使用枚举构建状态机的文章。这可以避免需要为每个状态在任何地方创建类,并且仍然支持一些继承。


在回答你的评论。

abstract class BaseState {
   public abstract boolean isPassive();
   public boolean increment() {
      System.out.println("increment "+(isPassize() ? "passive" : "active");
   }
}

class PassiveState {
   public boolean isPassive() { return true; }
}

如果你不想拥有多个 isPassive 方法,你可以假设一个类命名约定

public boolean isPassive() { return getClass().getSimpleName().startsWith("Passive"); }
于 2011-06-30T14:28:02.227 回答
1

我不确定是否完全理解您的问题。无论如何,我建议您将主动/被动状态建模为类中的属性,而不是使用继承。使您的层次结构类似于:

public class BaseState {
     boolean active; //active or passive
}

public class WaitingState extends BaseState {

}

...
于 2011-06-30T13:37:48.377 回答
0

如果您在状态机中共享常见行为,则有两种实现方式。

1)您可以将通用实现添加到基本状态,因此它可以被任何从基本状态继承的状态实现调用。这些方法的可见性将受到保护

2)在我看来,一个更好的解决方案是将常见行为移到它自己的类中,该类根本与状态类层次结构无关。
所以你可以考虑一个策略类,它实现了常见的行为,被基类引用,可以被任何状态调用。
第二种解决方案更好,因为它增加了状态机和策略类的可测试性。

于 2011-06-30T14:41:54.313 回答