
Você já viveu isso: seu sistema está cheio de regras de negócio importantes, mas elas estão emaranhadas com detalhes de banco de dados, chamadas de API externas e filas. Quando precisa trocar o banco, você mexe nas regras de negócio. Quando a API de pagamento muda, você altera a lógica central. Um pesadelo.
A Arquitetura Hexagonal (também chamada de Ports & Adapters) foi criada exatamente para resolver esse problema. Ela coloca o domínio – aquilo que torna seu negócio único – no centro, isolado de tecnologias externas. O resultado: sistemas mais testáveis, mais fáceis de evoluir e que vivem por muitos anos sem virarem legado indigesto.
Neste post, vamos entender os conceitos, ver exemplos práticos e descobrir por que essa arquitetura é uma aliada poderosa – mesmo sem usar frameworks ou linguagens específicas.
O problema da arquitetura tradicional em camadas
A clássica arquitetura em três camadas (apresentação → negócio → dados) tem uma falha sutil: a camada de negócio geralmente depende diretamente da camada de dados. Na prática, você acoplou suas regras de negócio ao banco de dados.

Se o banco muda, o serviço quebra. Se você adiciona uma API REST e também um CLI, precisa duplicar lógica. E testar o serviço exige um banco real – lento e frágil.
A proposta hexagonal: negócio no centro
A arquitetura hexagonal inverte a dependência. O domínio (regras de negócio) fica no centro, sem saber de nada externo. Tudo que entra ou sai do domínio passa por portas (interfaces). Cada tecnologia externa – banco, API, fila, UI – é um adaptador que implementa a porta adequada.

Analogia: O hexágono é o “núcleo do negócio”. As portas são tomadas (interfaces). Adaptadores são plugues que conectam o núcleo ao mundo externo.
Componentes essenciais
| Componente | Papel | Exemplo |
|---|---|---|
| Domínio (Entity) | Regras de negócio puras, sem dependências | Pedido, Cliente, Pagamento |
| Casos de uso (Use Case) | Orquestração de entidades para realizar uma tarefa | CriarPedidoUseCase |
| Portas de entrada | Interfaces que o mundo externo usa para chamar o núcleo | PedidoInputPort (método criarPedido) |
| Portas de saída | Interfaces que o núcleo usa para se comunicar com o exterior | PedidoRepositoryPort, EmailSenderPort |
| Adaptadores | Implementações concretas das portas | PostgresPedidoRepository, SmtpEmailSender |
Exemplo prático: processamento de pedidos
Vamos imaginar um sistema de e-commerce. O caso de uso: criar um pedido, calcular o total, verificar estoque (mock) e salvar.
1. Domínio puro (sem dependências externas)
// Java, mas vale para qualquer linguagem
public class Pedido {
private String id;
private List<Item> itens;
private Status status;
public double calcularTotal() {
return itens.stream().mapToDouble(Item::getPreco).sum();
}
public void aprovar() {
this.status = Status.APROVADO;
}
}
2. Porta de saída (interface que o núcleo espera)
public interface PedidoRepository {
void salvar(Pedido pedido);
Pedido buscarPorId(String id);
}
3. Caso de uso (orquestração, ainda sem tecnologia)
public class CriarPedidoUseCase {
private final PedidoRepository repository;
private final EstoqueServicePort estoque; // outra porta de saída
public CriarPedidoUseCase(PedidoRepository repository, EstoqueServicePort estoque) {
this.repository = repository;
this.estoque = estoque;
}
public void executar(Pedido pedido) {
// regra: verifica estoque antes de salvar
for (Item item : pedido.getItens()) {
if (!estoque.temDisponibilidade(item.getId(), item.getQuantidade())) {
throw new EstoqueInsuficienteException();
}
}
pedido.aprovar();
repository.salvar(pedido);
}
}
4. Adaptador concreto para banco PostgreSQL
public class PostgresPedidoRepository implements PedidoRepository {
private final DataSource dataSource;
@Override
public void salvar(Pedido pedido) {
// JDBC ou JPA – detalhe tecnológico
dataSource.getConnection().prepareStatement(...);
}
}
5. Montagem da aplicação (injeção de dependência)
// No "main" ou framework de injeção
PedidoRepository repo = new PostgresPedidoRepository();
EstoqueServicePort estoque = new EstoqueServiceAdapter(); // chama API externa
CriarPedidoUseCase useCase = new CriarPedidoUseCase(repo, estoque);
// Adaptador de entrada (ex: REST)
@RestController
public class PedidoController {
@PostMapping("/pedidos")
public void criar(@RequestBody PedidoDto dto) {
useCase.executar(dto.toPedido());
}
}
Vantagens reais:
| Benefício | Explicação |
|---|---|
| Testabilidade | Teste o caso de uso com mocks, sem banco ou API. Teste rápido e confiável. |
| Troca de tecnologia | Migrar de PostgreSQL para MongoDB? Crie um novo adaptador, o núcleo não muda. |
| Isolamento de domínio | Regras de negócio não vazam para camadas externas. |
| Múltiplos adaptadores | A mesma porta pode ter adaptadores REST, CLI, gRPC, etc. |
| Evolução independente | Equipes podem evoluir adaptadores sem mexer no núcleo. |
Quando NÃO usar arquitetura hexagonal?
- Projetos muito pequenos (CRUD simples) – o overhead não compensa.
- Times sem maturidade – exige disciplina de injeção de dependência e interfaces.
- POCs e protótipos – a velocidade de entrega inicial será menor.
Comparação com Clean Architecture e Onion
Hexagonal é muito semelhante à Clean Architecture (Uncle Bob) e Onion. Todas compartilham a ideia de inversão de dependência. A diferença principal é que Hexagonal foca nas “portas” (interfaces) e “adaptadores”, sendo visualmente mais simples de explicar.
Como começar com hexagonal
- Identifique seu domínio: quais são as entidades e regras de negócio que independem de tecnologia?
- Defina portas de saída: quais serviços externos seu domínio precisa (repositórios, APIs, filas)?
- Escreva casos de uso: implemente a orquestração usando apenas interfaces.
- Crie adaptadores: implemente as interfaces com tecnologias reais (banco, HTTP, etc.).
- Monte no entry point: o main ou framework injeta adaptadores concretos nos casos de uso.
Hexagonal em linguagens dinâmicas vs estáticas
- Java/C#/Go: use interfaces (ou structs com interfaces). Testes com mocks são diretos.
- Python/Ruby/JavaScript: use protocolos (duck typing) ou classes abstratas. A inversão de dependência acontece igualmente.
Conclusão: isole o que importa
A Arquitetura Hexagonal não é uma bala de prata, mas é uma ferramenta valiosa para sistemas que precisam durar. Ao colocar o negócio no centro e os detalhes tecnológicos nas bordas, você ganha flexibilidade, testabilidade e longevidade.
Na Jacobus Software, aplicamos esse padrão em modernizações de sistemas críticos. O resultado: clientes que conseguem trocar banco, fornecedor de pagamento ou infraestrutura de nuvem sem reescrever a alma do negócio.
