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:
- 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.
- 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.
- Definir dono para cada módulo e deixar explícito o que ele expõe para o resto do sistema.
- 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.