June 6th 2020
technology architecture design code
Domain Driven Design has been around for many years now. There have been many discussions, hundreds of articles, presentations, various talks, millions of lines of code written to better understand, explore and make the most of it. And yet we are still exploring for the better and I believe that’s the beauty of it.
What is it?
For me, it’s a way of capturing, communicating and implementing the business logic when building a software and primarily empowering the domain to control its own destiny and logic when doing so.
There is lots in the DDD toolbox. There is philosophy behind it, there is terminology. There are lots of design patterns and modelling approaches to promote better collaboration between techies and domain experts. And there are lots of material. I mean lots.
- focus on the domain core domain.
- explore the models in the core domain in collaboration with software and domain experts
- speak the ubiquitous language within the same bounded context
and some definitions again by Eric Evans, from the same reference.
domain : sphere of knowledge and activity where the application logic revolves. The subject area to which the user applies a program is the domain of the software.
model : a system of abstractions that describes selected aspects of a domain and can be used to solve problems related to that domain.
ubiquitous language : a language structured around the domain model and used by all team members within a bounded context to connect all the activities of the team with the software.
context : the setting in which a word or statement appears that determines its meaning. Statements about a model can only be understood in a context.
bounded context : a description of a boundary, (typically a subsystem or the work of a particular team) within witch a particular model is defined and applicable.
layered architecture : software divided into cohesive layers where each layer is only dependant on the layer below and loosely coupled to the layer above. Domain logic is isolated and put into a layer where is it separate from infrastructure and application logic. This allows the domain model to be rich and cohesive enough to capture essential business knowledge.
entity : an object where it is distinguished by its identity, rather than its attributes. Simple class definition, responsible for tracking its state and rules regulating its lifecycle.
value object: no need to track the identity of every object, especially when only the attributes and the logic of the object is important to the software. Make the object immutable, make operations side effect free that do not depend on any mutable state.
aggregate: unit of consistency. Root entity and cluster of entities and value objects within a defined boundary. External objects hold references only to the root entity. Properties and invariants are defined for the aggregate as a whole.
domain events : events that domain experts care about. Immutable facts, where the state of an entity can be inferred.
services : when a significant process or transformation in the domain is not a natural responsibility of an entity or value object, add and operation to the model as a standalone interface declared as a service.
repositories: provide query access to the aggregates in the ubiquitous language. A service that creates the illusion of an in-memory collection of all objects of that aggregate’s root type.
factories: Responsible for creating complex aggregates and structures so that the aggregate could be assembled consistently with entities and value objects enforcing its invariants. This way client code is not coupled to internal structure of the aggregate or the complex value objects.
Where to start?
I find the best way of exploring DDD is to have a high level understanding of its philosophy and terminology first, going through articles and then to look at the examples, see what others think, how it is applied to different domains and when it is applied. Even the author of the famous blue book finds it better to communicate it with an example.
Some good examples are;
And give it a try. Share it, get it reviewed, discuss.
Why would I bother?
Of course, DDD is not the answer to everything. (That is 42, for sure!) But it is a big step towards better understanding and communicating business logic and implementing in a more collaborative and more manageable way. It may be one of the best toolbox if it works for the domain we are building.
Improved communication within the team
Easier to review and track progress
Allows the team to focus on the business logic
Less duplication and more cohesion
The isolation of the business logic from the infrastructure and even the application logic forces a cohesive domain model. As a result the business logic is not scattered to the various layers of the software. It’s implemented in the domain model and available for reuse instead of implementing the same business logic and rules in different parts of the software.
Don’t overdue it in the beginning
Dumb-down domain layer
it could be the case you have a perfect layered application but with models which are merely data containers with no business logic. if you have a complex business logic but yet dumb data containers as model, then it is a smell that your business logic is probably scattered in your application, persistence and UI layers.
There are many problems with this approach:
- long and expensive tests due to fact that the core business functionality requires full assembly of all layers.
- unnecessary duplication of the code as the same rules could be implemented in different layers without being aware of each other.
- inconsistent behaviour could occur due to different implementations in different layers.
- difficult to change when there is a change in requirements. Similar changes will have to be reflected in all relevant layers.
it’s a different way of modelling software. Different approach which requires more time spent with domain experts to understand the business domain and learn to speak the same ubiquitous language. Many projects suffer from not having that much time in the beginning of the project.
There is also a huge tendency to implement business logic within application services, with the intention of reusable services. Some blames SOA, some claims this as miss-interpretation of SOA. Regardless, as more and more requirements are added with complex business logic then the services get fatter. The design once seemed clean and readable ends up complex, tangled, difficult to change with unnecessary duplication, difficult to test and far from the core domain.
DDD requires that initial investment on understanding the core domain. It also requires buy-in from the whole team which could be a new concept to many.