java - Java 中的重叠继承

标签 java inheritance multiple-inheritance overlap

我有一个重叠的继承层次结构。系统知道可以是客户、提供者和代理的人员。一个人必须属于这些类别之一,但可以属于两个或三个类别,即一个人可以同时是客户和提供者。

在数据库中,我认为问题已解决,每个类一个表(Person、Client、Provider 和 Agent 表)和一个从子类表的主键到父类(super class)表的主键的外键。 (欢迎任何可能的改进:))

问题来自 Java 世界,我不知道将此数据库设计映射到我的 Java POJO 的最佳方法。我有三种可能的糟糕解决方法:

  • 一个名为 Person 的独特类,具有子类中所有字段的联合。这将需要一个鉴别器字段才能知道哪种人。问题是一个不是客户而是提供者的人会将所有与客户相关的字段设置为空。

  • 一个名为 Person 的独特类,具有子类的所有公共(public)字段和三个“DTO 类”属性,其中包含与每个子类相关的字段。这样我们只有一个或两个字段为 null 而不是十个

  • Person 的一个抽象类和七个子类,三个子类的每个可能组合一个,即 Client、Provider、Agent、ClientProvider、ClientAgent ... ClientProviderAgent。 :S(当然,每个人都有对应的接口(interface))

这是一个网络应用程序。我使用 hibernate + spring 和 GWT 作为 UI

问题是:解决这个问题的最佳方法是什么?

最佳答案

IMO 继承不是对此建模的最佳方式,我会尝试组合。

您可以有一个 Person 类和几个 Role 类(实现一个公共(public)接口(interface),或者成为 Role 枚举的成员,具体取决于上下文),每个人都有一个或多个附加的 Roles。

通过这种方式,您可以轻松添加新的角色类型,并动态地将角色附加到一个人或从一个人身上分离角色。 (如果需要,您也可以有没有角色的人。)

粗略的例子:

interface Role {
  ...
}

final class Client implements Role {
  ...
}

final class Provider implements Role {
  ...
}

final class Agent implements Role {
  ...
}

class Person {
  List<Role> roles;
  public void addRole(Role role) { ... }
  public void removeRole(Role role) { ... }
  public Role getRoleOfType(Class<? extends Role> roleType) { ... }
}

更新:基于枚举的例子

这适用于角色对象没有状态的情况,因此您将相同的角色实例附加到每个人。

enum Role {
  CLIENT,
  PROVIDER,
  AGENT;
  // possible members, constructor etc.
}

Person 类几乎和上面一样,除了

  • 我使用 EnumSet而不是 List,因为这是专门为枚举量身定制的,
  • getRoleOfType() 在这里没有意义,所以我将其替换为 hasRole()

    class Person {
      Set<Role> roles = new EnumSet<Role>();
      public void addRole(Role role) { ... }
      public void removeRole(Role role) { ... }
      public boolean hasRole(Role role) { ... }
    }
    

关于java - Java 中的重叠继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3805395/

相关文章:

java - JFrame多种样式

grails - 如何从非域类继承 GORM 映射?

c++ - 警告 : defaulted move assignment operator of X will move assign virtual base class Y multiple times

带有另一个基类的 python 抽象方法破坏了抽象功能

java - 如何为自定义处理器配置 "initialise"方法

java - 递归通用用法

java - Application Insights 添加 http 过滤器

javascript - 在Javascript中, 'Object.create'和 'new'的区别

c++ - 将继承更改为虚拟的后果?

python numpy array/dict 多重继承