我正在尝试建立一个可以占据三个状态的类。在这三种状态下,对象的行为将完全不同。我不能为此简单地创建三个类,因为对象将在状态之间转换,并且我无法控制类的初始化方式。所有这三个状态必须在一个类定义下运行。

现在,要实现这一目标,我将执行以下操作

enum ServerType {
    primary,
    backup,
    idle
}
class ImportantClass {
   State myState;

   // Other fields

   void commonClassFunc() {
     if (state == idle) {
       idleFoo();
     } else if (state == primary) {
       primaryFoo();
     }
     ....
   }

   // Helper functions for State primary
   void primaryFoo() {
     // Access and mutate fields
   }
   ...

   // Helper functions for State backup
   void backupFoo() {
     // Access and mutate fields
   }
   ...

   // Helper functions for State idle
   void idleBar() {
     // Access and mutate fields
   }
   ...

}

您可以看到这将如何导致非常大的类定义,并且其状态特定部分仅由注释分隔。

我的目标是更雄辩地做到这一点。
例如,我可以创建一个Primary,Backup和Idle类,并让ImportantClass保留这些类之一,但是不允许这些方法访问公共字段。我想使用允许我像class ImportantClass implements Primary {}一样的接口,但不幸的是,即使我可以在此接口中定义primaryFoo方法,该方法仍然无法访问ImportantClass的字段。

您是否知道有什么方法可以构造此代码,以便可以在仍然访问ImportantClass的字段的情况下中断ImportantClass在这三种状态之间切换的行为?

最佳答案

解决该问题的一种方法如下:
创建一个新类(例如ImportantInfo)来保存状态之间共享的字段:要从ImportantClass和状态中访问的公共字段。
然后,您可以根据需要为每个状态创建类,并使它们采用ImportantInfo作为构造函数参数,每个方法都可以在这些字段上进行操作。因此,ImportantInfo的属性应具有公共权限。但是,您不会破坏封装,因为可以将ImportantInfo实例设为私有。
为了在相对于当前状态的所需动作之间进行切换,您应该具有使动作从通用抽象类继承的类。例如,让StateImplementor一个抽象类,该抽象类由ImportantInfo对象以及IdleImplementorPrimaryImplementor等作为子类构造。 StateImplementor将具有在这些类中实现的抽象方法Foo。要在实现之间切换,您应该在currentImplementor中有一个ImportantClass对象,并像这样切换:

void switchState(ServerType newState) {
    if (newState == ServerType.Idle)
        this.currentImplementor = new IdleImplementor(this.importantInfo);
}

09-11 20:31