Glossary

Domain-Driven Design

DDD helps when the problem is more complex than saving a form. Code can then talk about orders, reservations, and rules in the same language as the people who understand them.

Short definition

Design around the meaning of the problem, not a technical layer.

The domain is the part of reality addressed by the software: in an online store, for example, sales, pricing, inventory, shipping, and payment. DDD guides developers and domain experts to create a precise model and use it in conversation, requirements, tests, and names in the code.

It is not an ORM, a set of folders, or a requirement to introduce every well-known pattern. DDD is most useful when unclear terminology, many exceptions, or changing rules begin to cause defects and expensive misunderstandings.

The problem it solves

Ambiguous concepts and rules hidden in technical details

A model based only on tables often labels an important decision vaguely as a status, flag, or service. DDD seeks the meaning, boundary, and owner of the rule.

  • different interpretations of the same term across sales, customer support, and development
  • rules for orders, prices, reservations, or returns scattered across controllers and SQL
  • a marketplace integration that uses the same word differently from the internal application
  • business-rule changes that are difficult to locate and test
  • the need to separate the core of an important domain from general infrastructure

Practical example

Confirming a marketplace order and reserving inventory

In the Sales context, an Order can contain OrderItem, Money, and OrderStatus. The confirm() operation verifies that the order has at least one item, has not been cancelled, and its price uses the sales currency. Calling the warehouse does not belong in Order because it requires an external system; after validating the model, the application service therefore requests a reservation and only then stores the change in a transaction.

The marketplace may use “confirmed” for the moment it accepts a request, while internal Sales uses it for a commercially valid order. Translation at the integration boundary preserves both meanings and prevents an external status from directly overriding an internal rule.

PHP

final class Order
{
    public function confirm(): void
    {
        if ($this->items === [] || $this->status !== OrderStatus::draft()) {
            throw new DomainException('Objednávku nelze potvrdit.');
        }

        $this->status = OrderStatus::confirmed();
    }
}

Simplified flow

From a domain question to an executable model

DDD is not a linear process; this flow merely shows how the meaning of a rule moves into code and back to the people who verify it.

  1. Domain People describe the problem, such as when an online store may confirm an order and reserve inventory.
  2. Ubiquitous language The team clarifies terms such as Order, reservation, and payment authorization and what they mean.
  3. Bounded context The meaning applies within a defined area, such as Sales; another system may have a different model.
  4. Model and invariants Entities, values, and services express rules that must remain true.
  5. Application and integration An application service uses the model, stores the change, and translates it for a database or external system.

Main components

The strategic view defines boundaries; the tactical model defines rules within them

Not every application needs all these building blocks. What matters more is that the chosen model protects real decisions.

Domain and subdomains

The domain is the complete problem area addressed by the software. Subdomains divide it by purpose and complexity, such as sales, inventory, and payments; the greatest attention usually belongs to the area with a distinctive competitive rule, not necessarily every supporting function.

Ubiquitous language

The shared language is a working agreement about the meaning of words. If “order” means something different to inventory than to payments, using the same name alone does not solve the problem; a boundary is needed.

Bounded context

Defines where a model and its terms apply. Sales may understand a customer as a buyer, while CRM treats them as a contact with a communication history. A context is not automatically a microservice or database.

Entity and value object

An entity has a continuous identity, such as Order. A value object describes a value and is usually compared by content, such as Money or OrderStatus. A Doctrine entity is a technical mapping mechanism, not automatically a DDD entity.

Aggregate and aggregate root

An aggregate is a consistency boundary for a small group of objects. The root is the entry point through which state changes and invariants are protected. It is not created merely because every table should have its own aggregate.

Domain service, event, and repository

A domain service holds a domain operation that does not naturally belong to one object. A domain event records a meaningful fact. In DDD, a repository provides a collection of domain objects; it is neither a Git repository nor necessarily a universal CRUD layer.

Benefits and limitations

The model should reduce misunderstandings, not add ceremony

Benefits

  • named rules close to the model that gives them meaning
  • better conversations with people who understand the domain
  • clearer boundaries between system areas with different meanings
  • tests can read as concrete business scenarios instead of technical steps

Limitations and common mistakes

  • DDD is not a directory structure or a requirement to rename CRUD operations as commands
  • a Value Object for every primitive value can reduce clarity without protecting a rule
  • overly large aggregates increase conflicts and transaction complexity
  • introducing DDD without contact with a domain expert creates only an imagined model

Pragmatism

The depth of the model should follow domain complexity, not architectural ambition.

A simple catalogue, content administration interface, or one-off import may be clearest with a direct form, validation, and a few tables. Starting with a small vocabulary and several clear rules is often better than creating entities, repositories, and events for every field in advance.

DDD helps when rules recur, have exceptions, and cost money or trust when violated. Structure should reflect actual complexity: the model can evolve with team understanding and need not look the same in every context.

What to consider

The model tests both shared language and edge cases

Good questions about a change reveal more than mechanical use of a pattern.

  • name the rule in words understood by both a domain expert and developer
  • record invariants and examples in which the operation must fail
  • separate the same word with different meanings into its own contexts
  • do not let database structure dictate the API of the domain model
  • test model decisions without depending on HTTP or a particular ORM
  • review continuously whether an abstraction still protects real complexity

Common questions

DDD in practice

Is DDD the same as Clean Architecture?

No. DDD focuses on understanding the domain, its language, and its model. Clean Architecture mainly addresses dependency direction and the boundary around technical details. They can complement one another, but solve different problems.

Must every Doctrine entity be a DDD entity?

No. A Doctrine entity is an object mapped to persistence. A DDD entity is an object with identity and domain meaning; sometimes they coincide, and sometimes separating them is useful.

Are aggregates required for every table?

No. An aggregate is a consistency boundary for specific rules. Its size and existence follow from invariants and concurrency, not the number of tables.

Is a bounded context a separate microservice?

Not necessarily. It is primarily a boundary of a model and language. It can be a module in a monolith, a separate service, or simply a clearly separated part of the work of a team.

How I approach application design

I need to understand the rules before choosing technical boundaries.

For more complex processes, I clarify the meaning of terms, unusual states, and the responsibilities of application areas. Only then do I choose the depth of the model and automated checks.

Request a call

I will call you on the next working day between 9:00 and 17:00.

You can also call me directly.

+420 605 181 728

Leave your phone number and send a callback request.

By sending, you agree to processing your data in order to handle your request.