Overcoming complexity at the heart of DDD

This article is a translation of the material “Tackling Complexity in the Heart of DDD”.

Let’s do a little experiment: let’s try to explain the essence of domain-specific design (DDD) to someone who has no idea about it. This, especially if it is brief, is not easy. Bounded Contexts, Entities, Domain Events, Value Objects, Domains, Aggregates, Repositories … where do you start?

To find order in the seeming chaos, I want to analyze the DDD methodology from a rather unusual point of view – applying DDD to DDD itself. After all, this methodology is designed to work with complex domains, right?

Let’s start by defining the core of meaning: what is DDD’s main competitive advantage and what are the means to achieve it?

Core domain: Ubiquitous Language

In Domain-Driven Design: Tackling Complexity in the Heart of Software (Blue Book), Eric Evans argues that poor collaboration between domain experts and software development teams leads to the failure of many development efforts. DDD is committed to improving success rates by bridging this collaboration and communication gap.

To ensure the free exchange of knowledge, DDD calls for the development of a common, business-oriented language: a single language. This language should resemble a business domain and its terms, entities and processes.

A single language should be used extensively throughout the project. All communication should take place in this language. It should contain all the documentation. Even the code must “speak” the same language.

Many methodologies seek to reduce risk and increase the success rate of software projects, but since a single language is the vehicle for achieving DDD, I consider it to be the core of DDD.

Defining a single language is not a trivial task. Because software is bad at handling ambiguity, every term in a single language must have exactly one meaning. Unfortunately, human languages ​​don’t work that way – often words have different meanings in different contexts. To overcome this obstacle and support the development of a strict language, another DDD pattern is used: the Bounded Context.

Supporting Sub-Domain: Bounded Contexts

To prevent terms from having multiple meanings, DDD requires each language to have a strong context of applicability called limited context… This template defines a boundary within which a single language can be freely used. Outside of it, language terms can have different meanings.

Although the “bounded context” pattern is an integral part of DDD, I consider it a service subarea, since its purpose is to support the formation of a single language, a semantic core.

As I mentioned earlier, the code must also “speak” the same bounded-context language in which it is implemented. But how do you implement a business domain in code? There is no universal pattern for implementing a business domain. There are several options available and this is our next stop. Keep in mind: the sacred cows are about to suffer …

Generic Sub-Domain: Domain Implementation

These templates provide different ways to implement business domain logic:

  1. Transaction Script

  2. Active Record

  3. Domain Model

  4. Event-Sourced Domain Model

Each of these templates is suitable for a different level of complexity in the subject area. The template you choose should be expressive enough to embody a single language in your code. It is important to note that this solution is not set in stone. As the business evolves and the complexity of a single language grows, the implementation pattern can be upgraded to a more complex one.

The above four business domain implementation models are the ones that I am currently familiar with (original article posted April 6, 2016). Indeed, there may be others that I am currently not aware of. In the future, new ones may be invented. Their implementation is very different in different programming paradigms. Some of them are better suited to a certain programming paradigm, but difficult to implement in others. Given all this volatility, are they an integral part of DDD?

Since DDD methodology cannot cover all business domain implementation patterns, this know-how can and should be borrowed from other sources. For example, the transaction script, Active Record, and even the Domain Model are described in Martin Fowler’s book Patterns of Enterprise Application Architecture. By definition, the ability to rely on “out-of-the-box” solutions makes them non-specialized subareas. Yes, even the Domain Model template.

Effects

Separating DDD from tactical modeling patterns can have positive, far-reaching implications for the availability and diffusion of DDD. I want to focus on three of them: reducing the complexity of DDD, expanding its applicability, and the ability to get more value by moving to microservices.

The first consequence is a reduction in complexity

This map by Eric Evans depicts the patterns that make up DDD:

And here’s what it will look like if you discard the tactical modeling patterns:

Which one do you think will be easier to understand and explain?

Separating DDD from tactical modeling patterns will prevent many of the misconceptions and difficulties that many beginners face — for example, reading the first four chapters of the Blue Book and feeling like they are good at DDD. And speaking of the Blue Book, many complain that it doesn’t have enough code examples. Well, guess what? Once DDD is decoupled from tactical modeling patterns, no code samples are required at all. It is a pure systems modeling methodology that can be applied to any technology stack and any software paradigm.

Second consequence – broadening of applicability

I strongly disagree with the opinion that DDD should only be applied to complex projects. This concept stems from DDD’s strong association with the Domain Model template. Once we sever this connection, a whole new world of possibilities will open up.

Communication… No matter how simple a business domain is, if team members use different terminology for the same processes, sooner or later they will find themselves in chaos. The common language pattern prevents this scenario and provides a clear communication environment between all team members.

Business growth… Domain complexity is increased rather than decreased. This magnification is highest for so-called uncomplicated projects. Once this happens, the decision about the implementation pattern should be rethought and adapted to new levels of complexity.

Microservices

Microservices are very popular these days. Expanding the applicability of DDD to more project types will enable many microservice solutions to leverage the invaluable DDD tools. The bounded context pattern provides a business-oriented way of dividing the system into a set of independent services, and the Structure Map is a great way to map the topology of services and the patterns of interaction between them. (it is worth reading the article “Bounded Contexts are NOT Microservices»Vladislav Kononov, in which he rethought the relationship between the Bounded Context pattern and microservices)

“Are you crazy?”

This is what you are probably thinking about right now. However, I don’t think my proposal to remove tactical patterns from DDD is as crazy as it seems at first glance. Back at the DDD Europe 2016 conference, Eric Evans himself stated that the Domain Model implementation described in the Blue Book was conceived as a way to implement the domain model, but many mistakenly took it for a way to implement DDD. You see, tactical modeling patterns were never meant to be the one and only way to do DDD, but many people think they are.

Also, you cannot say that DDD is in perfect condition and has no reason to change. Unfortunately, the low rates of its implementation speak for themselves. DDD deserves a lot more attention than it gets. The blue book was published back in 2003, and since then the methodology has hardly changed. I believe this must change. Not because it’s bad – on the contrary, because it’s great. DDD has much, much more potential.

Final thoughts

It was not my intention to belittle the importance of tactical modeling in any way. On the contrary, this topic deserves much more attention than it receives. But in its own context. In addition to the Domain Model, there are many more patterns and more ways to implement them than can fit in a single DDD book. Moreover, these patterns can be implemented even in non-DDD projects, and a project can follow DDD principles even if it does not have a single unit.

Similar Posts

Leave a Reply Cancel reply