Pular para o conteúdo

Design Estratégico e Tático

Ambos os níveis são interdependentes. Vaughn Vernon insiste que aplicar apenas o tático — os “padrões chiques” de Entidades e Repositórios — sem o estratégico é o caminho mais rápido para um monólito acoplado com nomes bonitos. Comece pelo estratégico: entenda o negócio, separe subdomínios, desenhe fronteiras.

Dimensão Design Estratégico Design Tático
Pergunta Onde ficam as fronteiras? Qual modelo vale aqui? Como expressar e proteger o modelo?
Escala Sistema, times, subdomínios Classes, pacotes, métodos
Blocos Linguagem Ubíqua, Bounded Context, Context Mapping, Subdomínios Entidades, Value Objects, Agregados, Repositórios, Domain Services, Domain Events, Factories
Consequência de ignorar Big Ball of Mud, modelo canônico inchado Modelo anêmico, invariantes espalhadas

Lida com o panorama: como dividir um domínio grande em partes gerenciáveis e como essas partes se relacionam.

  • Core Domain: onde está a vantagem competitiva; recebe o maior investimento de modelagem.
  • Supporting Subdomain: apoia o core, específico do negócio mas não diferencial.
  • Generic Subdomain: problema resolvido (autenticação, e-mail); compre ou use pronto.

A Linguagem Ubíqua é o vocabulário comum, válido dentro de um Bounded Context — a fronteira de consistência do modelo. Cada contexto é candidato a microserviço e a um hexágono (Arquitetura Hexagonal).

O Context Map documenta como os contextos se integram, técnica e organizacionalmente:

Padrão Descrição
Partnership Dois times/contextos com sucesso ou fracasso conjunto; coordenam roadmap e integração.
Customer/Supplier Um contexto (upstream/fornecedor) atende às necessidades do outro (downstream/cliente), que tem voz nas prioridades.
Conformist O downstream adota o modelo do upstream sem tradução, por falta de poder de negociação.
Anti-Corruption Layer (ACL) O downstream cria uma camada de tradução que protege seu modelo do modelo do upstream.
Shared Kernel Dois contextos compartilham um subconjunto de modelo/código; exige forte coordenação.
Open Host Service (OHS) O upstream expõe um protocolo/API pública bem definido para múltiplos consumidores, muitas vezes com uma Published Language.
graph LR
    Vendas["Vendas (upstream)"]
    Faturamento["Faturamento (downstream)"]
    Estoque["Estoque"]
    Pagamentos["Pagamentos (externo)"]

    Vendas -->|Customer/Supplier + OHS| Faturamento
    Vendas -->|Shared Kernel| Estoque
    Faturamento -->|ACL| Pagamentos

Bounded Contexts não são desenhados a priori — são descobertos. A técnica mais usada é o Event Storming (Alberto Brandolini): especialistas de negócio e desenvolvedores, juntos diante de uma parede, reconstroem o fluxo do negócio com post-its de eventos de domínio no passado (“Pedido confirmado”, “Fatura emitida”, “Pagamento recusado”) dispostos em linha do tempo. Sobre eles se penduram comandos, atores, políticas e, por fim, os agregados.

Os cortes de contexto aparecem por sinais recorrentes:

  • A linguagem muda de significado — quando “Produto” passa a significar outra coisa na conversa, você cruzou uma fronteira (Linguagem Ubíqua).
  • Eventos-pivô — pontos onde o processo muda de fase e de responsável (“Pedido confirmado” separa Vendas de Faturamento).
  • Times e disputas de dono — se dois grupos brigam pelo mesmo conceito, provavelmente são dois modelos.
  • Dados que mudam juntos — invariantes imediatas apontam Agregados; consistência que tolera atraso aponta fronteira entre contextos, cruzada por Domain Events.
graph LR
    subgraph Vendas
        E1["Carrinho criado"] --> E2["Pedido realizado"] --> E3["Pedido confirmado"]
    end
    subgraph Faturamento
        E4["Fatura emitida"] --> E5["Pagamento aprovado"]
    end
    subgraph Logistica
        E6["Entrega agendada"] --> E7["Pedido despachado"]
    end
    E3 --> E4
    E5 --> E6

O resultado do exercício costuma ser o primeiro rascunho do Context Map — e a lista dos Domain Events que cruzarão as fronteiras.

Fornece os blocos de construção que dão vida ao modelo dentro de um Bounded Context.

Bloco Nota Papel
Entidade Entidades Identidade e ciclo de vida; igualdade por ID.
Value Object Value Objects Imutável, sem identidade; igualdade estrutural.
Agregado Agregados Fronteira de consistência com raiz que protege invariantes.
Repositório Repositórios Coleção de agregados; interface no domínio, adapter na infra.
Domain Service Domain Services Comportamento sem lar natural em entidade/VO.
Domain Event Domain Events Fato de negócio no passado; consistência eventual.
Factory (abaixo) Criação complexa de agregados com estado válido.

Quando a construção de um Agregado é complexa (muitas invariantes, montagem de VOs), uma Factory encapsula essa criação, garantindo que o objeto nasça consistente. Pode ser um método estático na raiz ou uma classe dedicada.

package com.loja.pedido.domain;
import com.loja.shared.domain.Dinheiro;
public class PedidoFactory {
private final PoliticaDeLimite politica;
public PedidoFactory(PoliticaDeLimite politica) {
this.politica = politica;
}
public Pedido novoPedidoParaCliente(ClienteId clienteId, PerfilCliente perfil) {
Dinheiro limite = politica.calcularLimite(perfil);
return new Pedido(clienteId, limite);
}
}
package com.loja.pedido.domain;
import com.loja.shared.domain.Dinheiro;
public interface PoliticaDeLimite {
Dinheiro calcularLimite(PerfilCliente perfil);
}
  • Só tático: implementar Entidades/Repositórios sem definir Bounded Context nem Context Map.
  • Conformist por inércia: adotar o modelo de outro contexto sem ACL onde a proteção era necessária.
  • Shared Kernel sem coordenação: compartilhar código entre times sem acordo, gerando quebras.
  • Investir no genérico: gastar modelagem tática cara em subdomínio genérico (autenticação, envio de e-mail, geração de PDF) em vez de comprar ou reusar. Reserve o esforço de DDD tático para o core domain.
  • Big Ball of Mud por falta de contexto: um único modelo tentando servir a todos os subdomínios, sem fronteiras explícitas.
  1. Qual a diferença entre design estratégico e design tático no DDD?
Resposta

Estratégico lida com a divisão em larga escala do domínio — Linguagem Ubíqua, Bounded Context e o mapeamento entre contextos (Context Map). Tático são os blocos de construção dentro de um contexto: Entidades, Value Objects, Agregados, Repositórios, serviços e eventos.

  1. Para que serve uma Anti-Corruption Layer (ACL)?
Resposta

Para traduzir o modelo de um contexto externo/legado para o seu, impedindo que conceitos alheios contaminem o seu domínio. É um adapter de tradução na fronteira entre bounded contexts.

  1. Por que classificar subdomínios em core, supporting e generic?
Resposta

Para direcionar investimento: o core é o diferencial competitivo e merece o DDD tático mais cuidadoso; supporting é necessário mas não diferencia; generic deve ser comprado ou reusado, não modelado do zero.

  1. Um Bounded Context é o mesmo que um microserviço?
Resposta

Não necessariamente. O Bounded Context é uma fronteira de modelo/linguagem; um microserviço é uma fronteira de deploy. Um contexto costuma ser um bom candidato a serviço, mas vários contextos podem coexistir num monólito modular.