Skip to main content

Domain Driven Design

Domain Driven Design (DDD) is a design pattern that models complex business processes (the “domain”) according to input from that domain's experts. Following the DDD pattern, business logic is contained within their contexts, resulting concise services that deal with a single opinion. As each service has one responsibility, they are individually smaller, easier to understand, and quicker to engineer.

Why is it a Good Pattern for us?

DDD shares and reinforces the principles of service-based architecture: to make small services based on clear and distinct contexts. DDD by definition requires your domains to be the central point of your architecture - we can then couple DDD and Service-based Architecture together by saying “each domain is a service”. Therefore, we get a service-based architecture “for free” by using the DDD pattern!

Pattern Concepts

There’s a few important concepts in DDD that are used to transfer our business model into an architectural model. There are many fantastic resources (See External Resources), but a summary of they key concepts and points are described below.

Domains

A Domain itself is a “sphere of knowledge” - that is, a contained area of a business. A domain is commonly, but not limited to, an operative group within a business area, such as Menu Management with a Restaurant, or Invoicing within Finance.

📒 See these fantastic resources for a deeper dive on Domains:

👓 Bounded Contexts

DDD recognises that context is important in business, so our code should behave in the same way. An over simplified example is that an Order to a Customer will mean something different to an order to a Restaurant, hence an order’s context is different, depending on who’s “using” it. As such, our business domains should be structured and arranged with respect to their Bounded Contexts.

In practical terms, we already know that Customer and Restaurant will have separate domains, as they are unique “spheres of knowledge”, but bounded context recognises that an Order is an entirely different concept, and therefore implementation, that just happen to called “Order”.

Decoupling contexts results in “pure” domains, where we can implement business logic without any dependencies.

📒 See these fantastic resources for a deeper dive on Bounded Contexts:

Ubiquitous Language

If both the Customer and Restaurant domains have a concept of an “Order”, won’t it get confusing if we name them both “Order”? Naming something is hard - A name is often either permanent or very hard and/or costly to change once it’s been adopted (Individual Choice, anyone?!), so choosing the correct name is of paramount importance.

Ubiquitous Language is the process of coming up with a dictionary of business language within a domain, regardless of the influence of other domains. That is, we should call something for what it is, not for what something else is, or was. Product, Design and Engineering should be able to use the Ubiquitous Language to communicate without any ambiguity to the domain experts.

For example, the Customer and Restaurant using the “Order” language seems like a simple problem, but we can expand this further. Customer Care, Accounts and Sales may also have context of an Order, so if we wanted to uniquely name each context, we have to think of 5 different names for an “Order”, whereas the respective teams may use an entirely different term day-today.

📒 See these fantastic resources for a deeper dive on Bounded Contexts:

Aggregates and the Aggregate Root

Aggregates are used to represent the components (concepts) of a given bounded context. They are comprised of Entities and Value Objects. An Aggregate Root is the name given to one of those Entities that allows access to all of the Aggregates features (business logic).

Martin Fowler elaborates on this in his article (linked below):

💬 Aggregate is a pattern in Domain-Driven Design. A DDD aggregate is a cluster of domain objects that can be treated as a single unit. An example may be an order and its line-items, these will be separate objects, but it's useful to treat the order (together with its line items) as a single aggregate.

An aggregate will have one of its component objects be the aggregate root. Any references from outside the aggregate should only go to the aggregate root. The root can thus ensure the integrity of the aggregate as a whole.

📒 See these fantastic resources for a deeper dive on Aggregates:

Designing a Domain

DDD models your business processes according to your domain experts, so in order to implement DDD successfully, you must first understand your business process.

Building a DDD-based Service

DDD focuses on the domain, so when building a DDD-based service, we must provide isolation for our business logic. This is achieved by using the Layered Architecture pattern.

External Resources