Domain-Driven Design

Domain-Driven Design (DDD) is an approach to designing modular software systems by managing the complexities of business domains. The core idea is that a business domain’s strategy and needs should be the driving forces behind the system’s design decisions. For the design to reflect business strategy and needs, you must first acquire that knowledge.

Domain Analysis

DDD provides a set of tools for exploring business domains. It all starts with domain analysis and the identification of subdomains. Subdomains are cohesive units of functionality needed to succeed in the overarching business domain. The goal is not only to identify the business building blocks but also to evaluate their strategic importance. Subdomains are categorized into three types:

Once subdomain boundaries are identified, a deeper understanding of the business domain and the intended system behavior is needed. This is achieved through the practice of ubiquitous language: forming a shared understanding and a shared language between software engineers and business domain experts.

Strategic Design

Traditionally, software systems were designed around a single model of the business. This model aimed to cover the entire domain and enable the implementation of all possible functionalities. However, such all-encompassing models quickly became huge, unmanageable, and complex–defying their original purpose.

DDD advocates a different approach: working with multiple models, each designed to address a specific aspect of business functionality. Models are driven by semantic conflicts in potential ubiquitous languages. To limit the applicability of each model, a clear boundary is required: its bounded context.

A bounded context is an explicit area where a model can be applied. In DDD, it serves as a boundary for a model, the project/service it is implemented in, and its ownership–the team responsible for its evolution and maintenance. These are strategic design decisions, shaping the system’s coarse-grained components and the allocation of engineering teams’ responsibilities.

Although bounded contexts encapsulate models and aim to reduce dependencies among them, they are not completely independent and have to interact with each other. To that end, DDD describes a set of integration patterns suitable for different levels of collaboration and communication among teams. These include shared kernel, partnership, conformist, anti-corruption layer, open-host service, and separate ways. These patterns differ in their cross-team collaboration levels and types of communication interfaces, ranging from ad-hoc to formal integration approaches.

Once the required models, their boundaries, and the appropriate integration patterns are established, the next step is implementing the models’ functionality. This is the tactical design aspect of DDD.

Tactical Design

A number of business logic implementation patterns can be used depending on the complexity of the models:

Business logic implementation patterns influence the choice of an application architecture pattern: layered architecture, ports-and-adapters (hexagonal architecture), or CQRS (Command-Query Responsibility Segregation). These patterns define how a bounded context’s internal components are structured and integrated.

From Domain to Design

The domain-driven design methodology provides a comprehensive set of patterns and practices for acquiring domain knowledge and using it as the foundation for strategic and tactical design decisions. All these tools have something in common: coupling.

DDD and Balanced Coupling

Many of the discussed patterns and practices directly relate to the dimensions of coupling:

Ultimately, in the balanced coupling model, DDD’s subdomains are often used to evaluate the volatility levels of software components.


Learn More