【问题标题】:DDD: Instantiate Value objects inside Aggregate or pass it as parameter?DDD:在 Aggregate 中实例化 Value 对象还是将其作为参数传递?
【发布时间】:2017-01-13 23:00:49
【问题描述】:

在创建聚合时,我们应该在聚合内部创建值对象,还是应该将已经创建的值对象传递给 ctor 或工厂。

 public Booking(DateTime arrivalDate, DateTime departureDate)
 {
      this.ArrivalAndDepartureinformation = new ArrivalAndDepartureInfo(arrivalDate, departureDate);
 }

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

【问题讨论】:

  • 问题是:你如何使用那些构造函数,那些构造函数的参数是从哪里来的?

标签: domain-driven-design value-objects


【解决方案1】:

在 Aggregate 中实例化 Value 对象还是将其作为参数传递?

  • 如果我们谈到将参数传递给构造函数,这取决于它的使用方式。可能存在一些可能需要使用原始类型的基础架构限制。

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

一般来说,我会说最好将值对象传递到您的聚合中

值对象可以:

  • 让你的模型语言更具表现力
  • 带类型安全
  • 封装验证规则
  • 自己的行为

【讨论】:

  • 所以发送到应用服务的输入参数用于构造值对象,然后发送到聚合工厂或构造函数
  • 是的。您可以在模型中获得更少的参数、更具体的参数类型和更具表现力的语言。
【解决方案2】:

我推荐的一般准则是这样的:

  • 在域模型内部,尽可能使用值对象。
  • 将原语转换为域模型边界的值对象(控制器、应用程序服务)。

例如,而不是这个:

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】:

    领域模型应该说领域,而不是实现原语。

    您的应用程序组件通常负责获取原始数据并以模型的语言表达。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-13
      • 1970-01-01
      • 2014-02-14
      • 2011-03-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多