Como Tudo se Conecta
O mapa mental
Seção intitulada “O mapa mental”graph TD
SOLID["SOLID<br/>princípios de design"]
DDD["DDD<br/>o que vai no núcleo"]
ARQ["Hexagonal / Clean<br/>como organizar em volta"]
SOLID -->|"DIP habilita a inversão"| ARQ
SOLID -->|"SRP/OCP guiam as classes"| DDD
DDD -->|"Entidades, VOs, Agregados<br/>preenchem o núcleo"| ARQ
ARQ -->|"protege"| DDD
Nível 1 — SOLID é o alicerce
Seção intitulada “Nível 1 — SOLID é o alicerce”Os princípios SOLID operam no nível da classe e do módulo, mas explicam por que as arquiteturas funcionam:
- O DIP é literalmente o mecanismo por trás de Ports e da Regra da Dependência. Uma “porta” nada mais é que uma abstração da qual tanto o núcleo quanto o detalhe dependem.
- O OCP é o resultado: com o domínio dependendo de interfaces, você adiciona um novo adapter (novo banco, novo protocolo) sem tocar no núcleo.
- O SRP justifica separar caso de uso, entidade e adapter — cada um tem uma razão distinta para mudar.
- ISP mantém as portas pequenas e coesas; LSP garante que adapters diferentes de uma mesma porta sejam de fato substituíveis.
Nível 2 — DDD preenche o núcleo
Seção intitulada “Nível 2 — DDD preenche o núcleo”Hexagonal e Clean definem uma “caixa” no centro (o núcleo / as Entities), mas não dizem o que colocar dentro. É o DDD que fornece o conteúdo:
- Entidades e Value Objects são as regras de negócio corporativas (as Entities da Clean).
- Agregados definem as fronteiras de consistência dentro do núcleo.
- Repositórios são o exemplo canônico de uma driven port: interface no domínio, implementação como adapter.
- Domain Services e casos de uso preenchem a camada de aplicação / Use Cases.
- Um Bounded Context costuma virar um hexágono (ou um serviço) inteiro.
Nível 3 — Hexagonal e Clean são a mesma foto
Seção intitulada “Nível 3 — Hexagonal e Clean são a mesma foto”Como detalhado em Comparação - Hexagonal vs Clean vs Camadas, as duas arquiteturas descrevem a mesma estrutura com vocabulários diferentes. Escolher entre elas é secundário; o que importa é: domínio no centro, dependências apontando para dentro, tecnologia nas bordas atrás de portas.
Um exemplo mental costurando os quatro
Seção intitulada “Um exemplo mental costurando os quatro”Imagine um caso de uso “transferir dinheiro entre contas”:
- DDD modela
Contacomo agregado,Dinheirocomo value object com invariantes (saldo não negativo), e define a interfaceContas(repositório = driven port). - Hexagonal/Clean posicionam a
Contano núcleo, o serviçoTransferirDinheirocomo caso de uso atrás de uma driving port, e a implementação JPA deContascomo adapter secundário. - DIP garante que
TransferirDinheirodependa da interfaceContas, não do Spring Data. - OCP permite trocar o adapter JPA por um de outro banco, ou adicionar um adapter de mensageria, sem tocar na regra de transferência.
Veja isso em código em Exemplo Hexagonal com Spring e Exemplo Clean com Spring.
Onde coloco este código?
Seção intitulada “Onde coloco este código?”A dúvida prática mais comum depois de aprender os pilares:
graph TD
Q{"Nova logica de negocio:<br/>o que ela faz?"}
Q -->|"valida ou deriva o valor<br/>de um conceito"| VO["Value Object"]
Q -->|"muda o estado de um objeto<br/>com identidade"| ENT["Entidade / raiz do Agregado"]
Q -->|"regra que cruza<br/>varios agregados"| DS["Domain Service"]
Q -->|"orquestra transacao,<br/>repositorios e eventos"| AS["Application Service / Use Case"]
Q -->|"reage a um fato<br/>que ja aconteceu"| EV["Domain Event + listener"]
Q -->|"traduz formato<br/>ou protocolo"| AD["Adapter"]
| Se a lógica… | Vai para | Nota |
|---|---|---|
| Valida ou deriva um valor (CPF, dinheiro, vigência) | Value Object | Value Objects |
| Protege estado e invariantes de um objeto rastreável | Entidade / raiz de agregado | Entidades, Agregados |
| Envolve vários agregados numa regra de negócio | Domain Service | Domain Services |
| Coordena repositórios, transação e publicação de eventos | Application Service / interactor | Application Services, Use Cases |
| Reage a algo que já aconteceu, sem acoplar o autor | Domain Event + listener | Domain Events |
| Converte JSON/SQL/fila de e para o domínio | Adapter | Adapters |
Cheiro → diagnóstico
Seção intitulada “Cheiro → diagnóstico”Os sinais de alerta espalhados pelas notas, consolidados para revisão rápida:
| Cheiro no código | Provável violação | Onde estudar |
|---|---|---|
switch/instanceof sobre “tipo” espalhado pela base |
OCP | OCP - Open-Closed Principle |
UnsupportedOperationException em override |
LSP (e quase sempre ISP) | LSP - Liskov Substitution Principle, ISP - Interface Segregation Principle |
| Descrever a classe exige a palavra “e” | SRP | SRP - Single Responsibility Principle |
new de infraestrutura dentro da regra de negócio |
DIP | DIP - Dependency Inversion Principle |
import jakarta.persistence/org.springframework no domínio |
Regra da Dependência | A Regra da Dependência |
| Entidade só com getters/setters + service gigante | Modelo anêmico | Entidades, Domain Services |
| Um repositório por tabela | Agregado mal delimitado | Agregados, Repositórios |
Evento nomeado no imperativo (ConfirmarPedido) |
Comando confundido com fato | Domain Events |
| Entity ou tipo de framework atravessando fronteira | Vazamento de fronteira | A Regra da Dependência, Ports |
| Duas raízes de agregado na mesma transação, sem decisão consciente | Fronteira transacional | Agregados |
Interface com vocabulário técnico (salvarNaTabela) |
Inversão de fachada, sem inversão real | DIP - Dependency Inversion Principle, Ports |
| Regra de negócio em controller ou adapter | Núcleo vazando para a borda | Adapters, Use Cases |
Ordem de adoção recomendada
Seção intitulada “Ordem de adoção recomendada”Quando NÃO usar nada disso
Seção intitulada “Quando NÃO usar nada disso”Um CRUD sem regras de negócio relevantes não se beneficia de portas, agregados ou boundaries — vira cerimônia pura. O custo dessas abstrações só se paga quando existe domínio complexo que vale a pena proteger da tecnologia. Reconhecer isso é, em si, uma aplicação madura de SOLID e do bom senso arquitetural.
Relações
Seção intitulada “Relações”- Home
- SOLID
- Domain-Driven Design
- Arquitetura Hexagonal
- Clean Architecture
- Comparação - Hexagonal vs Clean vs Camadas
- Testando o Núcleo
- Exercícios Práticos
Perguntas de revisão
Seção intitulada “Perguntas de revisão”- Por que se diz que o DIP é o “fio” que conecta SOLID às arquiteturas?
Resposta
Porque portas (Hexagonal) e a Regra da Dependência (Clean) são aplicações diretas do DIP: núcleo e detalhes dependem de abstrações definidas pelo núcleo, com a infraestrutura implementando-as.
- Qual o papel do DDD dentro de uma arquitetura Hexagonal ou Clean?
Resposta
Preencher o núcleo/Entities com um modelo rico: entidades, value objects, agregados, repositórios (como portas) e serviços de domínio. A arquitetura fornece a caixa; o DDD, o conteúdo.
- Um repositório do DDD corresponde a que elemento arquitetural?
Resposta
A uma driven port (Hexagonal) / output boundary-gateway (Clean): interface definida no domínio, implementada por um adapter de infraestrutura.
- Qual sinal indica que aplicar essas abstrações seria overkill?
Resposta
Um domínio essencialmente CRUD, sem regras de negócio relevantes a proteger. Aí portas, agregados e boundaries adicionam custo sem retorno.