AAAlison AmorimBlog
alisonamorim.com ↗

Arquitetura

Por Que Sua Arquitetura de Software Está Falhando (e Como Consertar)

Por que decompor por funcionalidade ou domínio faz a arquitetura falhar e como a volatilidade, de Righting Software, orienta um design que aguenta mudança.

  • 6 min de leitura
  • Arquitetura
Fonte do texto
Blocos de concreto em neon se partindo em estilhaços no centro de uma rede de conexões e linhas de código, a arquitetura que desmorona
Neste artigo · 7 seções
  1. A crise real
  2. Por que isso acontece?
  3. As armadilhas clássicas
  4. A verdadeira raiz: volatilidade
  5. Então como consertar?
  6. Um exemplo que você já viu
  7. Insights & Takeaways

Se você conseguiu chegar até aqui neste artigo, provavelmente já viu seu sistema virar um emaranhado incompreensível. Ou conhece alguém que viu. Na real, é difícil conhecer alguém na engenharia que não viu isso acontecer.

Aqui está o incômodo: não é coincidência. Não é simplesmente “coisa de software”. Não é culpa do prazo impossível, nem da mudança de requirement (requisito) de última hora (bem, também é, mas não é a causa raiz). A verdade, que ninguém gosta de admitir, é que a maioria das arquiteturas falha porque foi construída sobre alicerces errados desde o dia um.

A crise real

Vamos aos fatos. Em Righting Software, Juval Löwy descreve a indústria de software como vivendo uma crise multidimensional que afeta praticamente tudo: custo, agenda, requisitos, equipe, manutenção e qualidade.

Custo: A correlação entre o orçamento planejado e o que você realmente gasta é fraca. Muito fraca. Pior ainda: mesmo quando o custo da primeira versão faz sentido, o custo ao longo da vida do sistema explode porque o design não acomoda mudanças. Em muitos casos, as empresas chegam ao ponto de jogar o sistema fora e reescrever tudo do zero, em vez de mantê‑lo por décadas como acontece com aviões comerciais ou infraestrutura física.

Agenda: Deadlines viram construtos abstratos que ninguém leva a sério. Quando um time realmente cumpre a data, os colegas ficam surpresos. A realidade é que o design ruim causa mudanças que se propagam por todo o sistema, invalidando trabalho já feito.

Requisitos: Times resolvem os problemas errados. Há uma falha constante de comunicação entre clientes e desenvolvimento. E mesmo quando os requisitos são perfeitamente comunicados, eles vão mudar; quando mudam, muitas vezes invalidam o design inteiro.

Equipe: Até sistemas modestos ficaram tão complexos que ultrapassaram a capacidade do cérebro humano de entendê‑los. Essa complexidade vem de arquitetura ruim, que leva a sistemas confusos, difíceis de manter e estender.

Manutenção: A maioria dos sistemas não é mantida pelas mesmas pessoas que desenvolveram. Novos desenvolvedores não entendem como funciona e acabam introduzindo novos problemas ao tentar resolver os antigos. Custos explodem, o tempo de resposta aumenta e volta a tentação de reescrever tudo.

Qualidade: Francamente, é a parte mais quebrada. Software tem bugs. A palavra “software” virou sinônimo de bug. Consertar um bug frequentemente cria dois novos, especialmente se a arquitetura não favorece testabilidade, entendimento e manutenção.

Tudo isso acontece ao mesmo tempo. Não é um problema; são vários, se alimentando entre si.

Por que isso acontece?

Talvez a sua intuição seja culpar metodologia, falta de DevOps (integração entre desenvolvimento e operações), ausência de testes automatizados ou a “cultura”. Tudo isso ajuda, mas não é a raiz.

A raiz é design inadequado. Não de padrão de código ou escolha de framework. De arquitetura. De como você quebra o sistema em componentes.

Pense assim: você pode ter o melhor time do mundo, com testes excelentes, DevOps bem implantado, metodologia ágil e ferramentas modernas. Se a arquitetura for uma bagunça, você ainda vai remar contra a maré. Todo dia. Por anos.

Juval faz uma observação que dói: antes, a maioria dos times tinha um veterano que mentoria os mais novos e passava o conhecimento de como decompor sistemas corretamente. Hoje, muitos desses mentores saíram ou se aposentaram. Quem ficou tem acesso a informação infinita, mas conhecimento muito limitado. Aí fica fácil cair nas armadilhas clássicas.

As armadilhas clássicas

Existem duas formas muito populares de decompor sistemas que parecem lógicas, mas são destrutivas.

Decomposição funcional: Você olha para as funcionalidades do sistema, como autenticação, pagamentos, relatórios, e cria componentes em volta disso. Parece óbvio, certo? O problema é que, quando qualquer funcionalidade muda (e ela vai mudar), todo o sistema sente o impacto. Uma mudança em “pagamentos” afeta “relatórios” e “autenticação” porque tudo está entrelaçado. É como construir uma casa em que mexer em uma parede compromete a estrutura inteira.

Decomposição por domínio: Um pouco mais sofisticada. Você separa por domínios de negócio, “bounded contexts” ou microsserviços. O problema é que domínios não mudam no mesmo ritmo. Algumas partes do sistema evoluem rapidamente; outras ficam quase congeladas. Quando você agrupa tudo em uma unidade só porque faz parte do mesmo domínio, você herda a complexidade de ambas as partes, mesmo quando só uma está mudando.

Então como você deveria decompor?

A verdadeira raiz: volatilidade

Aqui entra o insight central de Righting Software: você deve decompor por volatilidade.

Você identifica quais partes do sistema vão mudar, quanto e de que forma. Depois agrupa o que muda pelo mesmo motivo e no mesmo ritmo, separando do que é estável. Separa também o que muda por razões de negócio daquilo que muda por razões técnicas.

Por exemplo: a interface com o usuário tende a mudar constantemente; UX é sempre revisitado. O esquema de banco de dados muda conforme o negócio evolui. Já o algoritmo de precificação pode ficar estável por anos. Nesse cenário, você separa: interface em um conjunto de componentes, dados em outro, regras de negócio em outro. Quando a área de UX pede um redesign, você consegue mexer apenas na camada de cliente, sem tocar no motor de precificação.

Consequência: mudanças ficam contidas, o retrabalho cai drasticamente, e os prazos deixam de ser uma piada interna.

Então como consertar?

Não tem mágica. Tem engenharia.

Primeiro, projete o sistema com base em volatilidade. Quebre o sistema em componentes guiado por como e quando cada parte muda, e não por funcionalidade ou domínio. Use uma arquitetura em camadas bem definida, com camada de cliente, camada de lógica de negócio, camada de acesso a recursos e camada de recursos. Separe o que muda do que é estável.

Segundo, valide o design cedo. Não espere anos para descobrir que a arquitetura é inviável. Use dias. Passe pelos casos de uso principais, simule fluxos de ponta a ponta e veja se a decomposição segura. Identifique problemas no papel, não em código.

Terceiro, projete também o projeto. Você não precisa só de arquitetura, precisa de um plano viável de execução. Isso significa calcular duração realista, custo realista e risco aceitável. Entender caminho crítico, folgas de cronograma, distribuição de equipe e trade‑offs entre tempo e custo. A maior parte dos times ignora completamente essa parte, e é por isso que tantos projetos explodem em prazo e orçamento.

No livro, Juval chama isso de The Method: system design mais project design. Um sem o outro não sustenta o resultado.

Um exemplo que você já viu

Você provavelmente já trabalhou em um projeto que começou “simples” e virou um Frankenstein. Timeline inicial de seis meses, que virou dois anos. Time que começou com cinco devs e terminou com vinte.

Quase sempre a arquitetura era funcional. Você adicionou uma feature; tudo pareceu bem. Adicionou outra, ainda bem. Na terceira mudança, a primeira começou a quebrar. Na quarta, as outras duas. Você “conserta”, mas cria efeitos colaterais escondidos. O projeto entra em espiral.

Com decomposição baseada em volatilidade, você teria identificado desde cedo que aquelas features respondiam a eixos de mudança distintos e precisavam ser isoladas em componentes diferentes. Quando a terceira feature exigisse mudança, as duas anteriores continuariam intactas.

A diferença é brutal.

Insights & Takeaways

  1. A crise em software é multidimensional: custo, agenda, requisitos, equipe, manutenção e qualidade se alimentam da mesma raiz, que é design inadequado.
  2. Decomposição por funcionalidade ou domínio é uma armadilha: parece lógica, mas faz com que mudanças se propaguem e o retrabalho exploda.
  3. Volatilidade é o driver real de design: separe o que muda do que é estável, mesmo dentro do mesmo domínio ou “feature”.
  4. Validação de design cedo reduz risco de forma dramática: dias de análise bem feita evitam meses de correções em produção.
  5. Project design é tão importante quanto system design: sem um projeto viável em tempo, custo e risco, até a melhor arquitetura morre na praia.

No fim das contas, você provavelmente já sentiu tudo isso empiricamente. A diferença é ter uma forma sistemática de pensar sobre o design, antes da próxima crise. É exatamente isso que Righting Software tenta colocar em forma de método.

Comente no LinkedIn

A conversa sobre este artigo acontece no LinkedIn, onde ele também foi publicado. Discordou de algo, viu de outro jeito em produção? Conta lá.

Leia também