java - 在抽象类的默认函数中使用类字段

标签 java software-design

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

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

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
   }
   ...

}

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

我的目标是以更 Eloquent 方式做到这一点。 例如,我可以创建一个 Primary、Backup 和 Idle 类,并让 ImportantClass 持有其中一个类,但这不允许这些方法访问公共(public)字段。我想使用允许我像 class ImportantClass implements Primary {} 这样的接口(interface),但不幸的是,即使我可以在此接口(interface)中定义 primaryFoo 方法,该方法仍然无法访问的字段重要类。

你知道我可以用什么方法来构建这段代码,这样我就可以中断 ImportantClass 在这三种状态之间切换的行为,同时仍然访问 ImportantClass 的字段吗?

最佳答案

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

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

关于java - 在抽象类的默认函数中使用类字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61265133/

相关文章:

java - 请问java RMI的意义?

python - 如何(惰性)从多个 python 模块加载相同的大数据集

java - <cms :include without <p> tag

java - 如何将带有 <String, Integer> 的自定义 header 添加到 Spring Boot HttpHeaders?

面向对象设计 : Car - Connection between Tank and Engine

docker - 从一个容器执行代码到另一个容器(即,从API容器在工作容器上执行脚本)

java - java中如何获取本地网络机器的MAC地址

java - 使用 javac 的错误类文件

java - Robolectric 测试从小部件启动的 Activity

julia - 保持/循环具有相同抽象父类型的对象集合的最佳实践 (Julia)