O poder do Anti-Corruption Layer (ACL)
No mundo ideal da arquitetura de software, trabalharíamos apenas em projetos perfeitos, criando microsserviços novos, com domínios limpos e tecnologias de ponta. No mundo real, a história é outra.
Como líderes de tecnologia e arquitetos, sabemos que a maior parte do nosso trabalho envolve integrar esses novos sistemas com o "legado". Aquele monolito ERP de 15 anos atrás, o sistema de faturamento do fornecedor externo ou aquele banco de dados com nomes de colunas indecifráveis.
O grande risco aqui não é técnico, é arquitetural: se você não tomar cuidado, o modelo de dados confuso e as regras de negócio obsoletas do sistema legado vão "vazar" para dentro do seu novo e limpo microsserviço. O resultado? Seu novo sistema começa a ficar acoplado às idiossincrasias do legado. Sua arquitetura limpa começa a se "corromper". Para evitar isso, precisamos de um guardião na fronteira. No Domain-Driven Design (DDD), chamamos isso de Anti-Corruption Layer (ACL).
O que é o Anti-Corruption Layer?
O ACL não é apenas um padrão de código; é uma estratégia arquitetural de defesa. Ele é uma camada que fica posicionada exatamente na fronteira entre o seu sistema moderno (seu Bounded Context) e o sistema externo/legado. O papel dele é simples, mas vital: traduzir e isolar. Ele garante que o seu domínio principal converse apenas a linguagem do seu próprio domínio. Quando ele precisa falar com o mundo exterior, o ACL entra em ação para converter os seus conceitos limpos para os conceitos "bizarros" do legado, e vice-versa. Se o sistema legado mudar sua API amanhã, a única coisa que muda do seu lado é a implementação interna do ACL. Seu domínio principal permanece intocado.
Por que usar? Os Benefícios Reais
- Desacoplamento Real: Você não depende das estruturas de dados do legado. Você depende de uma interface limpa que você mesmo definiu no ACL.
- Proteção da Linguagem Ubíqua: Seu time não precisa começar a usar termos confusos do legado (como "Tabela ZX90") dentro do código novo. O ACL traduz "Tabela ZX90" para "Cliente VIP", mantendo o código legível e alinhado ao negócio atual.
- Evolução Independente: O legado pode ser refatorado (ou substituído) sem quebrar seus novos serviços.
Um Exemplo Prático
Vamos imaginar um cenário clássico de e-commerce.
O Cenário:
Você está construindo um moderno Microsserviço de Catálogo. Para exibir se um produto está disponível para venda, você precisa consultar um antigo Sistema ERP Legado que gerencia o estoque físico.
O Problema:
O ERP Legado é antigo. Ele retorna dados de estoque em um formato XML confuso, onde o status do produto é um código numérico obscuro: 99 para "disponível", 01 para "bloqueado", 50 para "sem estoque".
A Abordagem Errada (Sem ACL):
Seu Microsserviço de Catálogo chama o ERP diretamente e seu código de domínio começa a ficar cheio de if (erpStatus == 99). Você acabou de poluir seu domínio com a lógica do ERP. Se amanhã o ERP mudar 99 para 100, você terá que caçar essa regra em todo o seu serviço.
A Abordagem Correta (Com ACL):
Você cria uma camada intermediária. O seu domínio define uma interface limpa, por exemplo, IEstoqueService, que retorna um objeto de domínio limpo chamado StatusProduto (um Enum com valores claros: Disponivel, Indisponivel, Bloqueado). A implementação dessa interface é o seu ACL.
Exemplo Conceitual (C#):
1. Seu Domínio Limpo (O que você quer proteger):
// No seu Domínio, tudo é claro e focado no negócio atual.
public enum StatusProduto
{
Disponivel,
Indisponivel,
Bloqueado
}
// Seu domínio define essa interface. Ele não sabe COMO ela é implementada.
public interface IEstoqueService
{
StatusProduto ObterStatus(string sku);
}
// Sua regra de negócio usa apenas conceitos limpos
public class RegraDeVenda
{
private readonly IEstoqueService _estoqueService;
// Injeção de dependência
public RegraDeVenda(IEstoqueService estoqueService) { ... }
public bool PodeVender(string sku)
{
// O código é limpo, sem "ifs" mágicos
var status = _estoqueService.ObterStatus(sku);
return status == StatusProduto.Disponivel;
}
}
2. O Anti-Corruption Layer (A Tradução):
Esta é a implementação da interface, que fica na camada de infraestrutura, longe do domínio. É aqui que a "sujeira" é isolada.
// Esta classe é o ACL. Ela conhece o legado e conhece o domínio novo.
public class ErpLegadoEstoqueAdapter : IEstoqueService
{
private readonly ErpClient _erpClient; // Cliente HTTP para o legado
public StatusProduto ObterStatus(string sku)
{
// 1. Chama o sistema legado (recebe o modelo "sujo")
var respostaXmlLegada = _erpClient.CallLegacyApi(sku);
int codigoLegado = int.Parse(respostaXmlLegada.SelectSingleNode("//statusCode").InnerText);
// 2. TRADUZ o modelo sujo para o modelo limpo do domínio
// Esta é a única parte do sistema que sabe sobre "99", "01", etc.
return codigoLegado switch
{
99 => StatusProduto.Disponivel,
50 => StatusProduto.Indisponivel,
01 => StatusProduto.Bloqueado,
_ => throw new Exception($"Código legado desconhecido: {codigoLegado}")
};
}
}
Conclusão
O Anti-Corruption Layer é um investimento na longevidade da sua arquitetura. Pode parecer um trabalho extra no início criar essas camadas de tradução (Adapters, Facades, etc.), mas o custo de não fazer isso é ter uma arquitetura nova que já nasce legada, acoplada e difícil de manter.
Em sistemas distribuídos, limites claros são essenciais. Use o ACL para definir e defender esses limites.
