DDD:在聚合内实例化值对象还是将其作为参数传递?

9
创建聚合时,应该在聚合内部创建值对象,还是应该将已经创建的值对象传递给构造函数或工厂?
 public Booking(DateTime arrivalDate, DateTime departureDate)
 {
      this.ArrivalAndDepartureinformation = new ArrivalAndDepartureInfo(arrivalDate, departureDate);
 }

或者

 public Booking(ArrivalAndDepartureinformation arrivalAndDepartureInfo)
 {
            this.ArrivalAndDepartureinformation = arrivalAndDepartureInfo;
 }

问题是:你如何使用那些构造函数,这些构造函数参数又从哪里来? - Ilya Palkin
3个回答

9
在聚合内实例化值对象或将其作为参数传递?
  • 如果我们讨论将参数传递到构造函数中,那么它取决于使用方式。可能存在一些基础设施限制,需要使用原始类型。

  • 如果我们讨论将参数传递到方法中,那么值对象是我100%的选择。

总的来说,我认为最好将值对象传递到聚合中。

值对象可以:

  • 使您模型的语言更具表现力
  • 带来类型安全性
  • 封装验证规则
  • 拥有行为

2
因此,发送到应用程序服务的输入参数用于构造值对象,这些值对象将被发送到聚合工厂或构造函数。 - Robert
是的。您可以使用更少的参数、更具体的参数类型和更具表现力的语言来构建您的模型。 - Ilya Palkin

6
我建议的一般准则是这样的:
  • 在域模型内,尽可能使用值对象。
  • 将原始类型转换为值对象,放在域模型(控制器、应用服务)的边界处。
例如,不要这样写:
public void Process(string oldEmail, string newEmail)
{
    Result<Email> oldEmailResult = Email.Create(oldEmail);
    Result<Email> newEmailResult = Email.Create(newEmail);

    if (oldEmailResult.Failure || newEmailResult.Failure)
        return;

    string oldEmailValue = oldEmailResult.Value;
    Customer customer = GetCustomerByEmail(oldEmailValue);
    customer.Email = newEmailResult.Value;
}

请执行以下步骤:

public void Process(Email oldEmail, Email newEmail)
{
    Customer customer = GetCustomerByEmail(oldEmail);
    customer.Email = newEmail;
}

3

领域模型应该使用领域语言,而不是实现细节。

你的应用组件通常负责将原始数据转化为模型语言。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接