---
title: "Domain-Driven Design"
type: "architectural-pattern"
slug: "domain-driven-design"
url: "http://localhost:3000/pt-br/architectural-patterns/domain-driven-design.md"
also_known_as: "DDD"
description: "Uma abordagem de desenvolvimento de software que centra o design em um modelo rico do domínio de negócio, expresso em uma linguagem compartilhada por engenheiros e especialistas do domínio."
languages: ["typescript"]
---
# Domain-Driven Design

_Also known as: DDD_

> Uma abordagem de desenvolvimento de software que centra o design em um modelo rico do domínio de negócio, expresso em uma linguagem compartilhada por engenheiros e especialistas do domínio.

## Intent

Enfrentar a complexidade no coração do software modelando o domínio de negócio explicitamente, e mantendo esse modelo — e o código que o expressa — em estreito alinhamento com a linguagem usada pelas pessoas que entendem o domínio.

## Problem

À medida que um sistema cresce, as regras de negócio tendem a se espalhar por controllers, services e queries de banco de dados. O código se distancia de como o negócio realmente fala sobre seu trabalho, então cada conversa precisa de tradução e cada mudança arrisca quebrar uma regra de que ninguém se lembrava.

Designs centrados em dados pioram isso: os modelos viram sacos anêmicos de getters e setters, as invariantes não vivem em lugar nenhum em particular, e o sistema lentamente se transforma em uma "grande bola de lama" que poucas pessoas se atrevem a tocar.

## Solution

O Domain-Driven Design ataca o problema em dois níveis.

O **design estratégico** divide um grande domínio em _contextos delimitados_ — fronteiras explícitas dentro das quais um modelo e sua linguagem são consistentes — e mapeia as relações entre eles. Cada contexto é livre para modelar o mesmo conceito de forma diferente onde o negócio genuinamente o enxerga de forma diferente.

O **design tático** constrói um modelo rico dentro de um contexto a partir de um pequeno conjunto de blocos de construção, e insiste em uma _linguagem ubíqua_: os mesmos termos aparecem nas conversas, no modelo e no código.

## Structure

Os blocos de construção táticos:

* **Entidades** — objetos definidos por uma identidade que persiste ao longo do tempo (um `Customer`, um `Order`).
* **Objetos de valor** — objetos imutáveis definidos por seus atributos (um `Money`, um `Address`).
* **Agregados** — clusters de entidades e objetos de valor com uma única _raiz de agregado_ que protege as invariantes do cluster e é o único ponto de entrada para mudanças.
* **Repositórios** — interfaces semelhantes a coleções que carregam e persistem agregados inteiros, escondendo os detalhes de armazenamento.
* **Serviços de domínio** — operações sem estado que não pertencem naturalmente a uma única entidade.
* **Eventos de domínio** — registros de algo significativo que aconteceu no domínio.

Os blocos estratégicos — **contexto delimitado** e **mapa de contextos** — organizam esses modelos entre equipes e subsistemas.

## Applicability

* Use-o quando a **complexidade central está nas regras de negócio**, não na tecnologia — logística, finanças, seguros, agendamento.
* Use-o quando várias equipes precisam concordar com um entendimento compartilhado e em evolução de um domínio.
* **Evite-o** em aplicações simples de CRUD ou entrada de dados, onde a sobrecarga de modelagem traz pouco retorno.

## How to Implement

1. Converse com especialistas do domínio e **destile a linguagem ubíqua**; anote os termos e o que eles significam.
2. Identifique o **domínio central** — a parte que dá vantagem competitiva — e concentre o esforço de modelagem nela.
3. Divida o domínio em **contextos delimitados** e desenhe um mapa de contextos com suas relações.
4. Dentro de um contexto, modele os **agregados** de forma que cada um imponha suas próprias invariantes em uma única transação.
5. Carregue e salve agregados por meio de **repositórios**; publique **eventos de domínio** para coisas com as quais outros contextos se importam.
6. Refine continuamente — o modelo nunca está “pronto”, ele evolui à medida que o entendimento se aprofunda.

## Pros

* Mantém o código alinhado ao negócio, então as mudanças mapeiam de forma limpa para os requisitos.
* Isola a complexidade por trás de contextos delimitados.
* Uma linguagem compartilhada reduz a má comunicação entre engenheiros e especialistas.
* A lógica de domínio rica é desacoplada da infraestrutura e fácil de testar unitariamente.

## Cons

* Curva de aprendizado íngreme e um investimento real em modelagem de domínio.
* Exagero para aplicações simples ou majoritariamente de CRUD.
* Requer acesso contínuo a especialistas do domínio.
* Mal aplicados, os blocos de construção viram cerimônia sem benefício.
## Relations

**Related patterns**

- [CQRS](/pt-br/architectural-patterns/cqrs.md)

## Code Examples

### typescript

```typescript
class Money {
  constructor(readonly amount: number, readonly currency: string) {
    if (amount < 0) throw new Error('amount must be non-negative')
  }
}

// Raiz de agregado: o único lugar onde as invariantes de Order são impostas.
class Order {
  private lines: { sku: string; qty: number }[] = []
  constructor(readonly id: string) {}

  addLine(sku: string, qty: number) {
    if (qty <= 0) throw new Error('quantity must be positive')
    this.lines.push({ sku, qty })
  }
}
```

