Pular para o conteúdo

Bounded Context

Segundo Eric Evans, um modelo só é coerente e sem ambiguidade dentro de limites bem definidos. O Bounded Context é esse limite: dentro dele, cada termo tem um único significado e o modelo é internamente consistente. Fora dele, o mesmo termo pode significar outra coisa.

Vaughn Vernon enfatiza que o Bounded Context é tanto linguístico (a linguagem ubíqua vale ali) quanto de implementação (um artefato de código, um deploy, uma equipe). Idealmente, um contexto pertence a um único time.

Sem fronteiras, tenta-se criar um modelo único para toda a empresa — o famigerado modelo canônico. Ele incha, todo termo vira genérico, e qualquer mudança quebra tudo. O Bounded Context permite que “Produto” no contexto de Catálogo seja rico em atributos de marketing, enquanto “Produto” no contexto de Estoque seja apenas SKU + quantidade.

Contextos precisam se comunicar. O Context Map documenta as relações e os padrões de integração entre eles (detalhados em Design Estratégico e Tático): Partnership, Customer/Supplier, Conformist, Anti-Corruption Layer (ACL), Shared Kernel e Open Host Service (OHS).

graph LR
    Vendas["Contexto: Vendas"]
    Faturamento["Contexto: Faturamento"]
    Estoque["Contexto: Estoque"]
    Pagamentos["Gateway de Pagamento (externo)"]

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

Relação com Arquitetura Hexagonal e microserviços

Seção intitulada “Relação com Arquitetura Hexagonal e microserviços”

Cada Bounded Context é implementado, na prática, como um hexágono independente. Ver Arquitetura Hexagonal:

  • O domínio do contexto fica dentro do hexágono, com sua própria linguagem ubíqua.
  • Integrações com outros contextos entram por Ports e são traduzidas por Adapters — frequentemente um Anti-Corruption Layer que protege o modelo interno de modelos externos.
  • Em microserviços, um Bounded Context costuma virar um serviço (ou um pequeno conjunto deles). O contrário — um serviço fatiado por camada técnica — é anti-padrão.
graph TD
    subgraph Contexto["Bounded Context: Faturamento"]
        subgraph Hex["Hexágono"]
            D["Domínio: Fatura, Cobrança"]
            PortIn["Port de entrada"]
            PortOut["Port de saída"]
        end
        AdIn["Adapter REST"] --> PortIn
        PortOut --> AdOut["Adapter: ACL p/ Pagamentos"]
        PortOut --> AdDb["Adapter: Spring Data"]
    end
    AdOut --> Ext["Gateway externo"]

Organização por contexto (pacotes ou módulos), cada um com seu próprio modelo. Um Anti-Corruption Layer traduz o modelo externo.

package com.loja.faturamento.domain;
import java.math.BigDecimal;
public record ClienteFaturamento(String documento, String razaoSocial, BigDecimal limiteCredito) {
public ClienteFaturamento {
if (documento == null || documento.isBlank()) {
throw new IllegalArgumentException("Documento obrigatorio");
}
if (limiteCredito == null || limiteCredito.signum() < 0) {
throw new IllegalArgumentException("Limite invalido");
}
}
}
package com.loja.faturamento.infrastructure.acl;
import com.loja.faturamento.domain.ClienteFaturamento;
import com.loja.vendas.api.ClienteVendasDto;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClient;
@Component
public class ClienteVendasAntiCorruptionLayer {
private final RestClient restClient;
public ClienteVendasAntiCorruptionLayer(RestClient.Builder builder) {
this.restClient = builder.baseUrl("http://vendas/api").build();
}
public ClienteFaturamento buscarPorId(String clienteId) {
ClienteVendasDto externo = restClient.get()
.uri("/clientes/{id}", clienteId)
.retrieve()
.body(ClienteVendasDto.class);
return traduzir(externo);
}
private ClienteFaturamento traduzir(ClienteVendasDto dto) {
return new ClienteFaturamento(
dto.cpfCnpj(),
dto.nomeCompleto(),
dto.creditoDisponivel()
);
}
}
  • Modelo canônico corporativo: um único modelo para toda a empresa; incha e acopla tudo.
  • Serviço por camada técnica: microserviços de “controllers”, “repositories” em vez de por contexto.
  • Ausência de ACL: consumir o modelo de outro contexto diretamente, deixando mudanças externas contaminarem seu domínio.
  • Contexto compartilhado por vários times sem acordo: gera conflitos e erosão da linguagem.

1. O que exatamente um Bounded Context delimita?

Resposta

A fronteira dentro da qual um modelo e sua Linguagem Ubíqua são consistentes e sem ambiguidade. Cada termo tem um único significado ali dentro.

2. Por que o “modelo canônico corporativo” é um anti-padrão?

Resposta

Porque força um único significado para cada termo em toda a empresa. O modelo incha, todo conceito vira genérico e qualquer mudança acopla e quebra múltiplas áreas.

3. Como o Bounded Context se relaciona com microserviços?

Resposta

Um Bounded Context costuma virar um microserviço (ou um pequeno grupo). Fatiar serviços por camada técnica, e não por contexto, é anti-padrão.

4. Qual o papel do Anti-Corruption Layer entre contextos?

Resposta

Traduzir o modelo externo para o modelo interno, isolando o domínio de mudanças e conceitos de outros contextos. É implementado como um Adapter na Arquitetura Hexagonal.