At my work we have initiated FridayForum's, which are an Open Space style gathering where any interested staff can participate in conversations about their favourite software topic. The intention is for any employee to present a tech talk on a topic of their choice, and engage their peers in a discussions, hopefully gaining some new insight as well as imparting some knowledge. the intention is that each session is about an hour long. I thought I'd go for 30 mins, and we ended up with nearly 2 hours of engaging discussion.
I kicked off the first session with an introduction to Domain Driven Design. I'm not going to write up the entire discussion in prose, but here are the notes. With the video to come, once production has been completed.
Domain Driven Design
History
- Software traditionally implemented using Transaction Script pattern.
- Business logic becoming increasing duplicated over time – DRY violated.
- As technology evolves the problem domain becomes increasingly complex.
- Need a way to succinctly model the problem domain and reduce maintenance times.
What is DDD?
- Strives to model the problem domain using object oriented techniques.
- Follows the Domain Model pattern (see Fowler’s PoEAA).
- Separates important business logic from secondary concerns such as infrastructure (and persistence) and presentation.
- Complexity is reduced by providing consistent terminology of artefacts used by both developers and the business, known as the ubiquitous language.
- Fights increasing complexity keeping related business logic in the one responsible class.
- Uses a layered architecture enabling a the domain model to be isolated within its own assembly and interact with other concerns via interfaces.
- DDD is a model of the business and it’s activities. The persistence mechanism should not influence the model.
How is DDD used?
- Identify business entities and build up a domain model using the relationships between entities. Easily done from the Use Cases / User Stories describing the system. An Entity is identified by one defining property. EG a Person entity is Id’d by social security number, or drivers license.
- Use the business language to name your entities. Eg. Shopping Cart, SKU, Album, Wishlist.
- Analyse the domain model and extract non-obvious domain entities (may not be physical entities).
- Identify Value Type objects – Value Types have no identity and should be immutable.
- Iterate.
- Identify Aggregates and Aggregate Roots.
- Aggregates are clusters of data that are treated as a single unit for the purpose of data changes.
- Aggregate roots are entities through which access to other entities should be made. The most obvious candidates for Aggregate roots are entities who are the 1 in 1:M aggregate/composition relationship. EG Invoice is the Aggregate root when dealing with InvoiceLineItems. An invoice line item is meaningful only the in the context of it’s invoice.
- A model has multiple Aggregate Roots and entities can be both Aggregate roots and participate in another relationship where it is not the Aggregate Root. Depends on the boundaries you identify from the Use Cases / Business.
- Once Aggregate Roots have been identified, One repository per Aggregate Root is created. When an Aggregate Root is returned, all related entities are also returned from the repository call.
- Determine Bounding Contexts. Sometimes multiple models exist in the one system. Bounding Contexts helps isolate models and ensure entities are misused. EG Wishlist may mean something different to the bigpond movies and bigpond music models. The context helps determine where the entities of a particular model can be used. Thereby reducing the chance of misuse or polluting another model/context. Also definite team members to work in the context.
- Use continuous integration to ensure bounding context is always valid.
- Where translation between Bounded Contexts is necessary use a Context Map.
- Anti-corruption layer’s protect the domain model from being corrupted by entities from a foreign domain. Typically used when communicating with third parties, and acting as a service boundary and providing translation between the two domains.
- Typically implemented using the Façade or Adapter patterns.
DDD is not…
- Anaemic Domain models: basically DTO’s and using the application layer services to implement business logic in a procedural manner.
- Domain entities contain business logic. Application layer services should only contain logic that cannot be assigned to an entity.