Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DDD: Instantiate Value objects inside Aggregate or pass it as parameter?

When creating aggregates, should we create value objects inside aggregates, or we should pass already created value objects to ctor or factory.

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

or

 public Booking(ArrivalAndDepartureinformation arrivalAndDepartureInfo)
 {
            this.ArrivalAndDepartureinformation = arrivalAndDepartureInfo;
 }
like image 345
Robert Avatar asked Sep 06 '16 13:09

Robert


2 Answers

Instantiate Value objects inside Aggregate or pass it as parameter?

  • If we speak about passing parameters into constructor, it depends on how it is used. There might be some infrastructure limitations that can require usage of primitive types.

  • If we speak about passing parameters into methods then Value Objects is 100% my choice.

In general, I'd say it is better to pass value objects into your aggregates.

Value Objects can:

  • make language of you model more expressive
  • bring type safety
  • encapsulate validation rules
  • own behavior
like image 154
Ilya Palkin Avatar answered Nov 02 '22 08:11

Ilya Palkin


The general guideline I would recommend is this:

  • Inside the domain model, use value objects as much as possible.
  • Convert primitives into value objects at the boundary of the domain model (controllers, application services).

For example, instead of this:

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;
}

Do this:

public void Process(Email oldEmail, Email newEmail)
{
    Customer customer = GetCustomerByEmail(oldEmail);
    customer.Email = newEmail;
}
like image 40
Vladimir Avatar answered Nov 02 '22 08:11

Vladimir