Creating Aggregate inside method of Another Aggregate

Viewed 51

So Let's Say I have:

  • Timesheet Aggregate
  • Member Aggregate (Which have role: Operator and Approver)

In Business Perspective, Operator will create timesheet according to their schedule work.

Previously, I using use case to check whether the role is valid or not

Using Use-Case:

createTimesheetUseCase(props)
  member = memberRepository(props.memberId); // assume always return member
  if (member.role != ROLE.OPERATOR)
    throw ForbiddenCreateTimesheet();
  timesheet = TimesheetFactory.create(props);
  timesheetRepository.save(timesheet);

But I wonder whether I can create Timesheet aggregate inside the Member Aggregate?

In code maybe something like this:

createTimesheetUseCase(props)
  member = memberRepository(memberId); // assume always return member
  timesheet = member.createTimesheet(props); // Will throw error if role is not operator
  timesheetRepository.save(timesheet);

Inside Member aggregate:

createTimesheet(props)
  if (this.role != ROLE.OPERATOR) throw ForbiddenCreateTimesheet();
  return TimesheetFactory.create({...props, memberId: this.id});

Is it violated the DDD and what's in your opinion the best way to handle this case ?

1 Answers

If it reflects the business language and business domain on how things happen, it can of course make total sense to have a factory method on an aggregate that has the responsibility to create another aggregate. If you use a separate factory class for that inside the aggregate is a technicality from my point of view.

Despite of following the domain language letting the member aggregate create the timesheet aggregate also works towards the Tell, Don't Ask. principle. Instead of asking member for some of its data to then do the job (executing business logic), the use case rather just tells the member to perform the respective operation. With that data and behavior are encapsulated better which is a good thing.

In his book Implementing Domain-Driven Design Vaughn Vernon describes exactly this as one possible adequate pattern for aggregate creation (see chapter 11, Factories). The code sample to that chapter can be found here.

Related