Home Comunidade Eventos YouTube Networks Desafios // produtos Academy News CTI | CVE Contato

03 - Conformist

#aderência#conformist#ddd#integração#trade-offs
video explicativo
Video explicativoEspaco reservado para o video desta anotação — adicione video: https://youtu.be/... no frontmatter da nota.

Conformist

O Conformist é a estratégia de integração em que o contexto downstream adota integralmente o modelo do upstream, sem camada de tradução e sem tentativa de preservar uma linguagem própria. O consumidor aceita as entidades, os estados, os nomes e até as distorções do modelo fornecido, porque o custo de proteger o próprio modelo é maior do que o benefício de tê-lo. Em produção, o padrão aparece com frequência em integrações com provedores externos, gateways de pagamento, serviços de entrega, plataformas de e-mail, e em relações internas de plataforma em que o fornecedor concentra todo o poder de decisão. A decisão de ser conformist é uma decisão de custo: você troca autonomia de modelagem por simplicidade de integração, e essa troca pode ser excelente ou um erro caro, dependendo da estabilidade e da qualidade do modelo upstream. O erro clássico é adotar a aderência por preguiça e descobrir, dois anos depois, que o modelo de terceiro foi costurado no coração do domínio próprio.

Conceito e natureza da aderência

Aderir significa assumir o modelo do upstream como parte do modelo próprio, dentro do contexto downstream. Se o gateway de pagamento chama o conceito de transação de Charge, com estados pending, settled e refunded, o contexto de cobrança passa a trabalhar com Charge e com esses estados, e não cria uma EntidadeDePagamento com tradução. O contraste é direto com a Anti-Corruption Layer, que existe justamente para impedir que conceitos externos contaminem o modelo local; o Conformist decide que a contaminação é aceitável, ou até desejada, porque o modelo externo é bom o suficiente.

A adesão tem gradações, e nomeá-las evita decisões confusas:

  • Aderência de tipo: o downstream usa os mesmos tipos e schemas, como DTOs gerados a partir do OpenAPI ou dos proto do upstream, e mantém nomes idênticos no código.
  • Aderência de estado: o downstream adota a máquina de estados do upstream, tratando settled e refunded como estados válidos do próprio modelo de negócio.
  • Aderência de processo: o downstream adota o fluxo imposto pelo upstream, como a sequência obrigatória de criação de cliente antes de cobrança, e desenha sua operação em cima dela.
  • Aderência de identidade: o downstream usa os identificadores do upstream como chave primária em suas tabelas, abrindo mão de identidade própria.

Quanto mais fundo a aderência, maior o ganho imediato de simplicidade e maior o preço futuro de sair. Aderência de tipo é reversível com esforço moderado; aderência de identidade é a mais difícil de desfazer, porque o identificador externo se espalha por todas as tabelas e integrações.

Na escala de estratégias do DDD, o Conformist ocupa a posição entre o Shared Kernel e a Anti-Corruption Layer. Com o kernel, os dois lados mantêm o modelo junto; com o conformist, o downstream apenas segue o modelo que não controla; com a ACL, o downstream constrói e protege o próprio modelo. A diferença entre seguir e compartilhar é de governança, e a diferença entre seguir e traduzir é de custo e autonomia. Identificar em que ponto dessa escala cada integração da sua arquitetura está é um exercício de dez minutos que revela riscos que ninguém tinha catalogado.

O problema que resolve

Entre contextos com relações desiguais de poder, o downstream tem três opções genéricas: traduzir, conformar ou isolar. Traduzir significa pagar uma camada de adaptação permanente, com testes, manutenção e risco de divergência; para um modelo upstream estável e bem desenhado, essa camada não protege de nada, apenas adiciona código. Isolar significa negar a integração, o que raramente é uma opção quando o upstream fornece capacidade essencial, como processamento de cartão. O Conformist resolve o dilema ao reconhecer que, em certas relações, o modelo upstream é o melhor modelo disponível, e a maior eficiência é usá-lo diretamente.

O padrão também resolve um problema de governança. Quando a empresa tem uma plataforma interna que atende múltiplos consumidores, exigir que cada consumidor crie sua própria tradução do modelo da plataforma multiplica o esforço total e fragmenta o entendimento. A aderência padronizada alinha todos os consumidores ao vocabulário da plataforma, reduz o custo de trocar pessoas entre times e torna a documentação da plataforma suficiente para todos.

Mecânica: adoção direta do modelo upstream

Na prática, a implementação conformist se reconhece por três marcas no código. Os DTOs do upstream atravessam a fronteira do serviço sem conversão, ou viram modelo de domínio com renomeação superficial. A persistência local grava estruturas espelhadas do upstream. A lógica de negócio do downstream consulta estados e atributos definidos pelo upstream.

# Conformist: o modelo do gateway vira o modelo do contexto, sem tradução
from gateway_pagamento.cliente import Cargo, StatusDeCargo

class ProcessadorDeCargos:
    def conciliar_cargo(self, cargo: Cargo):
        # o estado do upstream é tratado como estado do negócio local
        if cargo.status == StatusDeCargo.SETTLED:
            self.contabilidade.registrar_liquidado(
                id_externo=cargo.id,        # identidade do upstream como chave
                valor=cargo.valor_liquido,  # nomes e semântica do upstream
            )
        elif cargo.status == StatusDeCargo.REFUNDED:
            self.contabilidade.estornar(id_externo=cargo.id)
        else:
            # estados desconhecidos do upstream chegam ao consumidor
            self.fila_investigacao.colocar(cargo.id, motivo=cargo.status)

def resumo_por_status(cargos):
    # agregação local usa o vocabulário do provedor diretamente
    por_status = {}
    for cargo in cargos:
        por_status[cargo.status] = por_status.get(cargo.status, 0) + cargo.valor
    return por_status

Repare no tratamento de estado desconhecido, que é o ponto em que a aderência cobra o preço. O upstream pode introduzir um estado novo, como chargeback_notify, e o consumidor que não esperava esse estado precisa de um caminho de fallback, tipicamente fila de investigação, para não processar errado. Em desenho conformist, essa resiliência é obrigatória justamente porque não há tradução que normalize o que chega.

Ganho de simplicidade e perda de autonomia

O trade-off do padrão é único entre as estratégias de integração, porque tudo que uma estratégia ganha a outra perde de forma simétrica. Vale explicitar os dois lados antes de decidir.

Aspecto Ganho com aderência Perda com aderência
Código de integração Sem tradutor, sem adaptador, sem mapeamento Nenhum isolamento do formato externo
Velocidade inicial Integração em dias, documenta-se direto do upstream Renomear depois exige migração ampla
Evolução do upstream Mudanças compatíveis são adotadas sem custo local Mudanças incompatíveis chegam com força total
Qualidade do modelo Aproveita modelo maduro de plataforma consolidada Herda conceitos ruins, nomes ruins e decisões alheias
Independência de negócio Nenhuma discussão de vocabulário entre times Trocar de provedor exige reescrita do núcleo do contexto
Rastreabilidade Logs e erros usam o mesmo vocabulário do provedor Suporte de terceiro e time interno falam a única língua possível

A leitura da tabela em produção costuma ser assimétrica no tempo. No primeiro trimestre, a coluna de ganhos domina, e o time entrega rápido. No terceiro ano, a coluna de perdas domina, tipicamente na troca de provedor ou na exigência regulatória que o modelo externo não contempla. A decisão correta avalia o horizonte: para integrações com previsão de vida curta ou de troca frequente de fornecedor, a aderência é péssima; para capacidades estáveis que a empresa não quer diferenciar, é eficiente.

Quando aceitar

O padrão é escolha racional em um conjunto identificável de situações:

  • O upstream é um provedor externo com API madura e ampla adoção de mercado, e o domínio integrado não é diferenciador para o seu negócio.
  • O upstream é uma plataforma interna consolidada, com regime de versão sério, e a empresa prefere um vocabulário único em vez de dezenas de traduções locais.
  • O modelo upstream é de qualidade reconhecida, com conceitos bem definidos, e criar uma tradução só replicaria o mesmo modelo com nomes diferentes.
  • O contexto downstream é de suporte, com pouca lógica própria, e a chance de o modelo local divergir do fornecido é baixa.
  • A relação é de Customer-Supplier já bem estabelecida, e o downstream participou da formação do modelo upstream, de modo que aderir é endossar um modelo que já é seu em parte.

O denominador comum é a combinação de modelo upstream bom com baixa ambição de diferenciação local. Quando qualquer uma das duas condições falta, a tradução começa a se justificar.

Exemplo com API de provedor externo

O caso mais comum é a integração de checkout com provedor de pagamento. O modelo do provedor define Charge, com estados pending, authorized, settled, failed e refunded, ciclos de estorno e regras de captura parcial. Em desenho conformist, o serviço de ordens de pagamento adota esses tipos diretamente, gera os clientes a partir do schema do provedor e grava o estado da charge em tabela espelhada. O ganho aparece na velocidade: a equipe integra em duas semanas, sem desenhar modelo próprio, e a documentação do provedor serve como documentação interna.

O custo aparece nos dois cenários previsíveis. No primeiro, a empresa precisa migrar de provedor por questão comercial; como o identificador e os estados do provedor antigo atravessam o domínio, a migração vira reescrita do serviço, com conversão de dados históricos. No segundo, o negócio evolui para exigir parcelamento customizado ou split de recebíveis que o provedor não modela, e a ausência de modelo próprio impede expressar a regra, forçando soluções laterais no código. Nos dois casos, a conta do conformist é paga com juros, e a resposta correta costuma ser introduzir ACL gradualmente, começando pelo identificador e pelos estados.

Há também o custo silencioso de aprendizado. Em desenho conformist, os novos integrantes do time aprendem o domínio de pagamento pela documentação do provedor, e os conceitos internos, como política de estorno e regra de conciliação, ficam implícitos no código sem vocabulário próprio. Times que operam nesse regime por anos relatam a mesma dificuldade em entrevistas de modelagem: a linguagem ubíqua local simplesmente não existe, porque toda nomenclatura é emprestada. Esse efeito é reversível, mas só com investimento deliberado em reconstrução de vocabulário.

Comparação com outras estratégias

Estratégia Tradução do modelo Acoplamento com upstream Custo inicial Custo em 3 anos
Shared Kernel Nenhuma, código é comum Máximo, release conjunto Baixo Alto, com governança
Customer-Supplier Nenhuma a leve, modelo negociado Alto, com contrato e pactos Moderado Moderado, sob estabilidade
Conformist Nenhuma, adota o modelo alheio Alto, unilateral Mínimo Depende da estabilidade do upstream
Anti-Corruption Layer Total, na fronteira Baixo, o modelo local é soberano Alto Baixo, mudanças externas ficam na fronteira

Sinais de que a aderência começou a custar caro

A decisão de migrar de conformist para tradução raramente é tomada cedo demais, quase sempre é tomada tarde. Alguns sinais antecipam o ponto de inflexão:

  • Regras de negócio locais começam a ser codificadas como casos especiais sobre estados do provedor, porque o modelo externo não tem conceito para elas.
  • O número de condições no código que comparam texto de estado externo cresce a cada release do upstream, sem nenhuma abstração local.
  • Discussões de produto trocam o nome do conceito de negócio pelo nome do campo da API, sinal de que o vocabulário externo engoliu o interno.
  • A troca de provedor entra no radar comercial, e a estimativa técnica de migração assusta a gestão.
  • Testes dependem de ambiente de sandbox do provedor, e a instabilidade externa vira a principal causa de pipeline vermelho.

Quando dois ou mais sinais coexistem, o plano realista é a tradução gradual: introduzir a camada por um único conceito, tipicamente o identificador ou o estado, e avançar conceito a conceito em releases normais, sem grande projeto de reescrita. A tradução gradual preserva a vantagem que motivou a aderência original, que era velocidade, enquanto devolve ao contexto o controle sobre o vocabulário e a identidade.

Erros comuns e boas práticas

Sintoma em produção Causa raiz Mitigação
Migração de provedor vira projeto de um ano Identidade e estados externos espalhados pelo domínio Aderir por tipo, nunca por identidade
Novo estado do upstream quebra processamento Sem caminho de fallback para estado desconhecido Fila de investigação e handler de estado não previsto
Equipe não entende os próprios dados Vocabulário do terceiro sem glossário interno Glossário que mapeia conceito externo à operação
Regra de negócio sem lugar para morar Modelo externo não expressa a regra local Introduzir tradução parcial antes de hackear a regra
Testes acoplados a sandbox instável do provedor Aderência sem contratos gravados Gravar interações e testar contra gravações

A prática mais valiosa em desenho conformist é a aderência seletiva, que adota tipos e estados, mas preserva identidade própria. Manter uma chave interna com a chave externa como atributo mantém a reversibilidade da decisão, e o custo extra é mínimo. A segunda prática é a resiliência de vocabulário: todo switch de estado do upstream precisa de ramificação default explícita, porque provedores adicionam estados sem pedir licença, e o consumidor sem fallback processa errado em silêncio. A terceira é registrar a decisão: um parágrafo no repositório declarando que o contexto é conformist, com a data e as condições avaliadas, transforma uma escolha em política revisável, em vez de deixar que ela se eternize por inércia.

A revisão da política merece cadência, tipicamente anual ou quando o contrato comercial do provedor é renegociado. O registro da decisão transforma a pergunta de revisão de estilização arquitetural em verificação factual: as condições que justificaram a aderência ainda valem, e a resposta alimenta ou a continuidade ou o plano de tradução gradual descrito na seção anterior.