orm 和 java 中的 DDD 实体

bas*_*iat 1 design-patterns domain-driven-design

我开始阅读 E. Evans DDD 的第 5 章,并尝试对这些概念进行头或尾。

在 ddd 的上下文中,什么是实体,什么不是实体,什么是值对象?

在我的 Hibernate 映射中查看Value 对象或实体对象?- 但它是关于 Hibernate,而不是 DDD,我问的是 DDD

  1. 在上面的休眠订单线示例中是实体,但订单线仍然是 DDD 实体吗?
  2. 更一般地说,我们可以说任何 jpa/Hibernate @Entity 是 DDD 实体,还是不是?
  3. 在我看来,OrderLine 是 Jpa/Hibernate 实体的一个很好的例子,它不是 DDD 实体,是吗?

例如,如果我们使用了某个对象数据库,我们可能会将 Order 与其 OrderLines 一起存储,不是吗?

  1. 在关系数据库方面,我们可以说,在数据库中映射为 OnDeleteCascade 的 Jpa @Entity 不是 DDD 实体,但它仍然是一个值对象?
  2. hibernate @Embedded 总是一个 DDD 值对象吗?(似乎是的,它没有身份)

好的,现在还有其他疑问。假设我们有两个不同的系统,一个是 Java,另一个是 Python。一个用于计费,另一个用于营销。他们都有一个客户实体。

  1. 我们是否说 BillingCustomer 是与 MarketingCustomer 相同的 DDD 实体(假设它们都代表同一个客户 John Doe,生于 01.01.1980,ssn 12-34-56)?这意味着在 java 中两个不同的类,即使没有共同的父类(除了来自 Object)也可以表示相同的 DDD 实体。如果是这样,应如何在上述类中实现 equals ?
  2. 对于表示相同 DDD 实体的两个不同 Java 类,java equals 是否应该返回 true?

人们常说实体是可变的,而值对象是不可变的。

  1. 我们将如何使用 java 和 hibernate 在下面实现:

    @Entity Person 有 @Embedded Address,Person 类有 getter 和 setter,而 Address 只有 getter ?要更改地址街道,我们会像 person.setAddress (Address.builder(person.getAddress()).setStreet("newStreet").build()) 那样做?

Rob*_*gam 5

寻找所有这些的客观答案可能很困难,因为存在多种相互矛盾的解释。

一般来说,DDD 实体和值对象与 ORM 实体和值有一些相似之处,但它们是非常不同的概念。主要原因有两个:

  • 两者所指的“身份”是不同的。数据库事物具有与数据库相关的身份,很少与业务相关的身份匹配,尤其是在非规范化时。
  • ORM 和 Persistence 一般是一种技术,与“业务”无关。
  • DDD 实体和值对象是对象而不是数据。我的意思是它们通常应该符合面向对象的原则,其中之一是对象应该关注行为而不是数据。这通常会导致对它们施加完全不同的力。

由于这些点,可能还有其他点,ORM 永远不应该混入“真正的”业务对象中。

因此,考虑到所有这些,让我们回答您的问题:

  1. 不,Hibernate Entity 永远不应该是 DDD Entity。
  2. 不,JPA/Hibernate 实体永远不应该是 DDD 实体。
  3. 正确的。
  4. 不,JPA 实体/值对象与 DDD 对象没有直接关系。
  5. 不,没有关系。
  6. 不,对象的身份可以指纯粹的概念性事物。BillingCustomer并且MarketingCustomer是概念上不同的东西,因此它们永远不会相等,即使它们背后的“真实”人类是相同的。一般而言,“真实”在软件设计中具有不同的含义。我们认为作为业务一部分(即无处不在语言的一部分)的一切都是“真实的”,即使其中一些甚至大部分不是传统意义上的“真实”。
  7. 不,equals() 也应该符合正常的 Java 规则。不同类的对象永远不应该相等。这将是非常混乱的。定义另一个关系,例如matches()、 或sameCustomer()等。
  8. 不知道你的意思。

哈。