System ArchitectureSoftware Architect

What is Domain-Driven Design (DDD) at the architecture level, what are the main building blocks of DDD, and how to implement bounded contexts?

Pass interviews with Hintsage AI assistant

Answer.

Domain-Driven Design (DDD) is an approach to designing software systems that focuses on the domain and its logic. DDD breaks down complex domains into related but independent bounded contexts. Within each context, a specific language (Ubiquitous Language) is developed in agreement with domain experts. The main building blocks of DDD include:

  • Entity: an object with a unique identifier and lifecycle (e.g., an order).
  • Value Object: an immutable object without a unique identifier (e.g., a shipping address).
  • Aggregate & Aggregate Root: a collection of objects where all changes go through the aggregate root.
  • Repository: a layer for working with the aggregate storage.
  • Service: operations not tied to a specific object.

Bounded contexts often represent separate microservices that interact through explicitly defined APIs or events.

Java code example (Spring):

// Example of Value Object @Embeddable public class Address { private String city; private String street; // ... constructors, equals, hashCode } // Example of Entity with Aggregate Root @Entity public class Order { @Id private Long id; @Embedded private Address deliveryAddress; // ... business methods }

Key features:

  • Clear decomposition of the domain and containerization of logic.
  • Simplification of development and scaling through isolation.
  • Increased consistency between technical and business language of the team.

Trick questions.

Are all objects in DDD Entities?

No, there are also Value Objects — they do not have uniqueness, and their state fully determines their identity.

Address a1 = new Address("Moscow", "Arbat"); Address a2 = new Address("Moscow", "Arbat"); System.out.println(a1.equals(a2)); // true

Does breaking into microservices mean applying DDD?

No, DDD can also be applied within a monolithic application by establishing internal bounded contexts.

Is a repository always needed for each aggregate?

Usually yes, but sometimes an aggregate can be fully stored as part of another aggregate if it is not the root of a separate business transaction.