我跟着这本关于Spring的书,在领域驱动的设计中,作者建模了一个具有一系列属性的货物实体。所讨论的两个属性是数字键和业务密钥(bookingId)。货物实体如下
**Cargo.java**
package whatever;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
@Entity
@Getter @Setter
public class Cargo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Embedded
private BookingId bookingId; // Business Identifier
}**BookingId.java**
package whatever;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Column;
import javax.persistence.Embeddable;
@Embeddable
@Getter @Setter
public class BookingId {
@Column(name="booking_id")
private String bookingId;
}如您所见,作者已经将业务密钥建模为嵌入式对象。在另一个对象中嵌入属性有什么好处?为什么我们不在货类中只设置一个名为bookingId的字符串变量,并对其强制执行唯一性约束呢?
发布于 2020-08-24 13:49:21
为什么不在货类中只设置一个名为bookingId的字符串变量,并在其上强制执行唯一性约束?
两个主要原因:
使用特定类型,而不是像String这样的通用基元,编译器可以将预订标识符与其他类型的字符串区分开来,从而减少了在需要位置标识符的地方不经意间传递预订id的更改。
此外,定义类(比如BookingId)可以将“需要知道底层数据结构的代码”与“不知道的代码”进行逻辑分离。换句话说,让预订标识符数据结构查询在一个地方都是有好处的。
(对于“标识符”而言,第二种类型往往不像模型中的其他值类型那么重要。在许多情况下,标识符在语义上是不透明的--你能对它们做的唯一真实的事情就是将它们相互比较。)
使用显式类型对信息进行建模还允许您减少操作空间,从而消除没有任何意义的方法。例如,获取预订id的子字符串可能无法实现任何有用的功能,因此您可以简化api,将其简化为在域模型中有意义的语义。
您将看到与集合类似的关注点;Lists和maps往往具有广泛的界面,因此它们支持许多可能的应用程序,但是配送域不是关于列表和地图,而是关于行程。标准库碰巧有一个方便的数据结构可供使用,这是实现的意外,而不是您试图建模的业务的一部分。
有关系吗?最终,机器实际上并不关心代码设计--但是下一个需要进行更改的人将受到设计的影响。通用DDD模式的部分动机是,代码的设计使程序员能够集中精力处理手头的任务(还请参阅“域代码”与“持久性代码”的分离,以及Evans 2003第6章中对生命周期模式的介绍)。
https://stackoverflow.com/questions/63561979
复制相似问题