Arquitetura de software não é o diagrama da apresentação. É o conjunto de decisões que define quanto custa mudar uma regra de negócio com o sistema já em produção. Três decisões concentram a maior parte desse custo: onde ficam as fronteiras do domínio, como o código se divide em módulos e como o sistema conversa com o que está fora dele.

Domínio: o que o sistema precisa decidir sozinho

Domínio é o conjunto de regras que a empresa executa todo dia e que o software precisa reproduzir sem alguém conferindo planilha. Antes de escolher framework ou banco, vale responder: quais decisões o sistema toma sozinho? Aprovar crédito, calcular frete, bloquear pedido, reservar estoque, liberar cobertura.

O erro comum é espalhar essas regras. Numa distribuidora de autopeças com ERP, WMS e portal de pedidos, a política de limite de crédito costuma aparecer em três lugares: no ERP, no portal e numa rotina noturna de conciliação. Enquanto o critério é estável, ninguém percebe. Quando a diretoria muda a regra para clientes com histórico de atraso, alguém ajusta dois pontos e esquece o terceiro. Semanas depois aparece o pedido liberado que não deveria passar, ou a venda travada para um bom cliente. Nenhuma linha de infraestrutura causou isso: a fronteira do domínio estava no lugar errado.

Regra de negócio relevante merece um único dono no código, com nome que a operação reconheça. Quando a regra mora em um serviço de domínio explícito, a mudança é uma alteração revisada. Quando mora em SQL espalhado, a mudança é uma caçada.

Modularidade: fronteiras que sobrevivem à troca de time

Módulo não é pasta. O teste prático: esse conjunto de código pode ser reescrito por outro time sem pedir permissão a ninguém? Se a resposta exige reunião com quatro pessoas, não é módulo, é arquivo.

Sinais de modularidade cosmética:

  • Um módulo lê tabelas de outro diretamente, sem passar pelo contrato dele.
  • Alterar o cadastro de cliente quebra o faturamento sem ninguém ter tocado no faturamento.
  • A pasta de utilidades cresceu mais que os módulos que deveria servir.
  • Nenhum módulo tem dono, então todos mexem em tudo.

Modularidade real aparece em dependências que apontam numa direção só e em dados que pertencem a alguém. Faturamento pode consultar clientes; clientes não precisa saber que faturamento existe.

Integrações: contrato antes do conector

Integração começa com uma pergunta de negócio, não com uma biblioteca: quem é o dono do dado? Se o cadastro de produtos nasce no ERP, portal e WMS são consumidores e precisam saber disso. Sem essa definição, cada sistema vira uma cópia parcial da verdade.

Um contrato de integração precisa cobrir formato e semântica dos campos, comportamento em repetição (a mesma mensagem chegando duas vezes não pode gerar dois pedidos), o que acontece quando o outro lado está fora do ar, versionamento e quem é acionado quando falha.

Integração ponto a ponto em malha é a dívida mais silenciosa da arquitetura: cada sistema novo precisa conversar com todos os anteriores, e o número de conexões cresce mais rápido que o time. Uma camada de tradução entre o modelo externo e o interno protege o domínio de mudanças que você não controla, típicas de integrações com fornecedores, bancos e transportadoras.

Na prática

Quem mantém software em produção pode começar por ações pequenas e verificáveis:

  1. Listar as cinco regras de negócio que mais mudaram no último ano e contar em quantos pontos do código elas estão implementadas. Mais de um ponto já é sinal de alerta.
  2. Desenhar o mapa real de integrações, com setas de quem chama quem e quem é dono de cada dado. Ele quase sempre diverge do diagrama oficial.
  3. Definir dono para cada módulo e deixar explícito o que ele expõe para o resto do sistema.
  4. Tratar integração nova como contrato: semântica, idempotência e plano de falha documentados antes do conector.

Arquitetura se prova na manutenção, não na apresentação. Sistema com fronteiras claras continua barato de mudar mesmo quando o time troca; sistema sem fronteiras fica caro até com o time mais experiente.