我正在尝试建立一个可以占据三个状态的类。在这三种状态下,对象的行为将完全不同。我不能为此简单地创建三个类,因为对象将在状态之间转换,并且我无法控制类的初始化方式。所有这三个状态必须在一个类定义下运行。
现在,要实现这一目标,我将执行以下操作
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
对象以及IdleImplementor
,PrimaryImplementor
等作为子类构造。 StateImplementor
将具有在这些类中实现的抽象方法Foo
。要在实现之间切换,您应该在currentImplementor
中有一个ImportantClass
对象,并像这样切换:
void switchState(ServerType newState) {
if (newState == ServerType.Idle)
this.currentImplementor = new IdleImplementor(this.importantInfo);
}