Home
img of docs

了解 DDD 中实体和值对象的定义和区别,学习如何在你的领域模型中应用它们来建模复杂业务逻辑。

chou403

/ DDD

/ c:

/ u:

/ 6 min read


一学一个不吱声

在领域驱动设计(DDD,Domain-Driven Design)中,实体(Entity)和值对象(Value Object)是两个重要的概念,它们用于描述系统中的对象及其行为。

实体(Entity)

实体是具有唯一标识的对象,它们在系统中具有独立的生命周期。实体的身份(ID)在整个系统中是唯一的,并且它的属性可能会发生变化,但其身份不会改变。

特点:

  1. 唯一标识: 每个实体都有一个唯一标识符,用于区分不同的实体实例。
  2. 独立生命周期: 实体具有独立的生命周期,可以单独存在并且会随着时间发生变化。
  3. 可变性: 实体的状态和属性可以随时间发生变化。

例子: 在一个电子商务系统中,用户(User)是一个实体,因为每个用户都有一个唯一的用户ID,并且用户的属性(例如名字,电子邮件地址)可能会随时间变化。

   public class User {
    private String userId;
    private String name;
    private String email;

    // 构造函数,getters,setters
}

值对象(Value Object)

值对象是没有唯一标识的对象,它们是通过属性来描述的。值对象是不可变的,即一旦创建,其状态就不能改变。值对象通常用于描述某种特定的属性或概念。

特点:

  1. 无唯一标识: 值对象没有唯一标识,它们通过属性值来判断是否相等。
  2. 不可变性: 值对象一旦创建,其属性值就不能改变。如果需要改变值对象的属性,通常是创建一个新的值对象。
  3. 用来描述特定概念: 值对象通常用于描述某个具体的概念或属性,而不需要单独存在。

例子: 在一个电子商务系统中,地址(Address)可以是一个值对象,因为地址只是描述一个具体的地点,并且它的属性(如街道,城市,邮政编码)一旦确定就不会改变。

   public class Address {
    private String street;
    private String city;
    private String postalCode;

    // 构造函数,getters
}

实体与值对象的比较

  • 身份: 实体有唯一标识,而值对象没有。
  • 生命周期: 实体有独立的生命周期,而值对象通常与其所在的上下文一起存在。
  • 可变性: 实体是可变的,而值对象是不可变的。

通过区分实体和值对象,DDD帮助我们更好地建模领域,确保系统中的对象能够正确反映业务需求并且易于维护和扩展。

举例说明实体和值对象

假设我们正在设计一个电商系统,需要设计一个订单类。订单包含多个订单项,每个订单项对应着购买了某个商品的数量和价格。

首先,我们定义一个订单项类,它包含订单号,商品名称,数量和单价4个属性,并且它们都是可变的,因为每个订单项都可以修改:

   public class OrderItem {
    private String productName;
    private int quantity;
    private BigDecimal unitPrice;
  	privatr String orderNo;
    //setter 和 getter
}

然后,我们定义一个订单类,它包含订单号,订单项列表,订单状态和订单总价四个属性。

   public class Order {
    private long orderId; // 实体
    private List<OrderItem> orderItems; // 值对象zh
    private OrderStatus status;
    private BigDecimal totalPrice;
}

我们在数据库中存储订单的时候,可以这样存储:

orderIdstatustotalPriceorderItems
2023021811223344CONFIRMED120{"productName":"《深入理解Java核心技术》 作者 Hollis","quantity":100,"unitPrice":129}

以上,订单就是一个实体,因为每一个订单对应一个单独的数据库记录,并且有唯一表示,就是订单号。而订单条目就是值对象,他是依赖于实体进行存储的。

在数据库中把数据取出来的时候,是可以把orderItems这个json类型的字段转成我们定义好的OrderItem的对象的。这样更方便我们进行操作。