Enterprise Java实体应该愚蠢吗?

2022-09-01 13:10:50

在我们的旧版 Java EE 应用程序中,有大量的值对象 (VO) 类,这些类通常只包含 getter 和 setter,可能和 .这些(通常)是要保存在持久性存储中的实体。(根据记录,我们的应用程序没有EJB - 尽管将来可能会改变 - 我们使用Hibernate来持久化我们的实体。在 VU 中操作数据的所有业务逻辑都在单独的类中(不是 EJB,只是 POJO)。我的OO心态讨厌这一点,因为我确实认为给定类上的操作应该位于同一个类中。因此,我有一种重构的冲动,将逻辑移动到相关的VO中。equals()hashCode()

我刚刚和一位在Java EE方面比我更有经验的同事进行了讨论,他证实,愚蠢的实体至少曾经是推荐的方式。然而,他最近也读到了质疑这一立场有效性的观点。

我知道有些问题至少限制了可以放在实体类中的内容:

  • 它不应该直接依赖于数据层(例如,查询代码应该进入单独的DAO)
  • 如果它直接向较高层或客户端公开(例如通过SOAP),则可能需要限制其接口

有没有更有效的理由将逻辑移动到我的实体中?还是需要考虑的任何其他问题?


答案 1

DTOVO应该用于传输数据,而不是嵌入逻辑。另一方面,业务对象应该嵌入一些逻辑。我之所以说一些,是因为在服务中放入的内容(协调涉及多个业务对象的逻辑)和放入业务对象本身的内容之间总能找到平衡。业务对象中的典型逻辑可以是验证、字段计算或其他一次仅影响一个业务对象的操作。

请注意,到目前为止,我还没有提到术语实体。持久性实体在ORM中得到了普及,我们现在尝试同时使用持久性实体作为DTO业务对象。也就是说,实体本身在层和层之间流动,并包含一些逻辑。

有没有更有效的理由不将逻辑移动到我的实体中?还是需要考虑的任何其他问题?

正如你所指出的,这都是依赖关系和你公开的内容的问题。只要实体是哑的(接近DTO),它们就可以轻松地隔离在一个专用的jar中,作为该层的API。您在实体中放入的逻辑越多,就越难做到这一点。注意你公开的内容和你所依赖的东西(加载类时,客户端也需要有依赖类)。这适用于异常、继承层次结构等。

举个例子,我有一个项目,其中实体在业务层中使用了一种方法。因此,实体的客户端依赖于 XML。toXml(...)

但是,如果您不太关心层,以及API和实现之间的严格分离,我认为在实体中移动一些逻辑是件好事。

编辑

这个问题已经讨论了很多次,并且可能会继续讨论,因为没有明确的答案。一些有趣的链接:


答案 2

我认为你的观点是有道理的。
有关详细信息,请参阅此处 - http://martinfowler.com/bliki/AnemicDomainModel.html
使用 JPA 时,实体是轻量级对象。因此,我认为其中的逻辑没有任何问题。

如果与 SOAP/Web 服务一起使用,我会添加一个单独的 Facade 层。