1

I am reading on DDD and I am trying to see how it would be applied in various situations.

So, let's take the example of a LoanApplication. To submit such an application the user would need to fill-in various Sections (e.g. PersonalDetailsSection, BusinessAssetsSection and so on).

Each of these sections is independent of the others, i.e. there are no invariants that will be violated if someone completely changes the PersonalDetailsSection but not the BusinessAssetsSection.

Moreover each of these sections is quite complicated on its own, with lots of one-to-many relationships so to me these sections are likely candidates for being different Aggregate Roots. The LoanApplication could be another AggregateRoot containing just the IDs of the separate sections (aggregate root).

On the UI front, the user fills in the details of each section in a wizard style screen (first the personal details, then the business assets and so on). At any time he or she can save a temporary version of the LoanApplication and in the end he or she can save a finalised version. Application finalisation means that it should be checked that all Sections contain valid information (e.g. no empty fields) and that no further changes to the application and each of the sections are allowed.

The first problem I have is that if I have each section as a separate AggregateRoot then whenever the user finalises the LoanApplication, then a series of checks and changes need to be made to all AggregateRoots (including LoanApplication). Is this an example of a Domain Service that I can use here with the purpose of making sure all sections contain valid data and finalising each one of them? Such a service would look like this

try {
  businessSection.finalise();
  personalSection.finalise();
  loanApplication.finalise();
  ...
} catch (InvalidDataException e) {
  //handle exception;
}

The second problem I have is about updating an Aggregate Root. An aggregate root may reference other aggregate roots by identity. So, let's say that a new Section is created and gets a new id. Now the LoanApplication aggregate root needs to reference the new id. Who is responsible for updating that in the LoanApplication ?

Thanks for any answers!

user2465039
  • 894
  • 1
  • 11
  • 28

1 Answers1

0

Moreover each of these sections is quite complicated on its own, with lots of one-to-many relationships so to me these sections are likely candidates for being different Aggregate Roots.

Yes, the fact that they don't have any overlapping consistency rules is a good sign.

The first problem I have is that if I have each section as a separate AggregateRoot then whenever the user finalises the LoanApplication, then a series of checks and changes need to be made to all AggregateRoots (including LoanApplication).

You probably want to think about this a slightly different way: when you are creating the instance of the Loan Application from the sections that have been prepared, you probably want to think of the information in those sections being immutable input values to the Loan Application aggregate.

Thus, the business logic of what it means to be a valid loan application are distinct from what it means to be a valid draft.

So, let's say that a new Section is created and gets a new id. Now the LoanApplication aggregate root needs to reference the new id. Who is responsible for updating that in the LoanApplication ?

The loan application is going to be the authority for its own state. Information outside of the application, like the fact that there is a new section, is communicated to the loan application aggregate as function arguments.

It sounds like the approach you want is: the section changes, and therefore that information should be sent to the loan application. There are lots of different ways you can arrange this - the aggregates can send each other messages, you can use a human as an intermediary, you can use a process as an intermediary, and so on.

VoiceOfUnreason
  • 52,766
  • 5
  • 49
  • 91
  • Thanks for the answer, but I am still unclear: for finalisation either all sections need to change their state (to read-only) or none (if validation fails). If LoanApplication accepts the sections as immutable input values, it can check for the general validity and update its own state but it cannot/should not update the state of the sections. Who should do that? In what kind of object/service will the messaging you propose take place? I was thinking of putting this in a Domain Service, but you seem to avoid suggesting it. – user2465039 Jan 16 '18 at 20:50
  • 1
    I would rather think the sections as Aggregate members of AggregateRoot of type LoanApplication, not as their own aggregate roots if this makes sense. The loanapplication is created, with the possibility of the sections not being in a valid state. Before finalizing, the LoanApplication can ask its sections are they in a valid state, and if they are, it can consider it self a valid application – tjugg Jan 16 '18 at 22:49