Voltar para Artigos
Arquitetura★ Destaque9 min de leitura

Clean Architecture e Arquitetura Hexagonal Explicadas

Entenda por que o seu Domínio (Regra de Negócios) deve estar no centro de tudo, totalmente isolado de frameworks, bibliotecas e banco de dados.

12 de agosto de 2026

Antigamente, as aplicações nasciam ao redor do Banco de Dados. Você criava as tabelas no MySQL, gerava os modelos e a aplicação era apenas uma 'casca' por cima disso. Se você precisasse trocar de banco (de MySQL para MongoDB), você precisaria reescrever a aplicação inteira.

Tanto a Clean Architecture (Robert C. Martin) quanto a Arquitetura Hexagonal (Alistair Cockburn) partem de um princípio oposto: o Banco de Dados, a Interface de Usuário e os Frameworks (como o Express) são apenas Detalhes.

O Domínio no Centro

No centro do sistema deve estar o seu Domínio (suas Entidades e Casos de Uso/Services). O centro não deve importar nenhuma biblioteca externa.

src/modules/orders/entities/Order.ts
// Repare: Não há imports do TypeORM, do Express, ou do AWS SDK.
// Apenas Typescript puro descrevendo a regra de negócio.

export class Order {
  id: string;
  total: number;
  status: 'PENDING' | 'PAID' | 'CANCELED';

  constructor(total: number) {
    this.total = total;
    this.status = 'PENDING';
  }

  public pay(): void {
    if (this.status !== 'PENDING') throw new Error('Invalid status');
    this.status = 'PAID';
  }
}

Portas e Adaptadores (Ports and Adapters)

A Arquitetura Hexagonal também é conhecida como Ports and Adapters. O seu núcleo de negócio declara Portas (Interfaces), dizendo: 'Eu preciso de algo que salve dados no banco'.

E as bordas do sistema criam Adaptadores (Implementações), dizendo: 'O TypeORM sabe salvar dados, vou implementar essa sua interface'.

src/modules/orders/repositories/IOrdersRepository.ts
// A PORTA (Fica no centro, dita as regras)
import type { Order } from '../entities/Order';

export interface IOrdersRepository {
  save(order: Order): Promise<void>;
  findById(id: string): Promise<Order | null>;
}
src/modules/orders/repositories/implementations/TypeORMOrdersRepository.ts
// O ADAPTADOR (Fica na borda externa, obedece as regras da Porta)
import type { IOrdersRepository } from '../IOrdersRepository';
import { getRepository } from 'typeorm';

export class TypeORMOrdersRepository implements IOrdersRepository {
  private ormRepo = getRepository(OrderModel);
  
  async save(order: Order): Promise<void> {
    await this.ormRepo.save(order);
  }
  // ...
}

A Regra de Dependência é estrita: A camada externa (Adaptadores, Frameworks) conhece a camada interna (Interfaces, Entidades). Mas a camada interna JAMAIS conhece a camada externa.

Conclusão

Apesar de exigir mais arquivos (Interfaces, Injeção de Dependências), uma arquitetura limpa blinda sua aplicação. Se o Express for descontinuado amanhã, você só precisa criar um novo Adaptador (Fastify, por exemplo). Suas regras de negócio (Services) ficam intocadas.