Design de Aplicações

Design de aplicações é um trema extremamente importante para o desenvolvimento de software. Vejo muitas pessoas não tendo ideia de como criar uma boa arquitetura, podendo criar grandes complicações à medida que o sistema vai evoluindo, novas features, novas demandas, problemas, pressão por entrega e muitos outros fatores que contribuem para o aumento da complexidade da aplicação.
Sistemas inteiores podem ser refeitos pelo simples fato do time não ter criado uma boa arquitetura, ao menos um início ideal que possibilite evolução e adaptação do projeto. Isso pode ocorrer por diversos fatores, falta de conhecimento e pressão para realizar a entrega (muito comum), este último cria uma armadilha por achar que pular etapas do software visando somente velocidade e entrega não vai afetar a qualidade e escala.
Neste artigo vou abordar alguns problemas que podem ocorrer por não seguir um padrão bem definido. O meu objetivo é trazer a visão do desenvoveldor de software e coisas que ele deve se preocupar para mitigar problemas futuros, para ele e para a empresa.
⚠️ Este artigo não é uma crítica pessoal. Eu mesmo já cometi muitos desses erros/eganos. A ideia aqui é compartilhar aprendizados que fui acumulando ao longo da jornada, pra ajudar outros devs a evitarem problemas comuns.
Armadilhas de um design de arquitetura ruim - Speed vs Design
Antes de começar a falar como desenvolvo uma arquitetura vou abordar as armadilhas que a falta de um bom design de software pode acarretar na sua aplicação.
Algumas coisas que estão aqui podem ser corroboradas com o livro Arquitetura Limpa
do Robert C. Martin (Uncle Bob) onde o autor fala no primeiro capítulo sobre custos que aumentam por não criar uma boa arquitetura.
Atuo com desenvolviento de software a mais de 10 anos e ao longo da minha jornada vi muitas coisas. Atuei desde pequenos sistemas de backoffice até grandes empresas de E-commerce, Telefonia, Bancos, Financeiras, LLM, destas muitas com milhões de transações diárias, e por incrível que pareça elas tinham problemas em comum, a falsa velocidade para entrega de software.
Não vou entrar no mérito de desenvolvimento ágil, nos dias de hoje é mais do que comum temas como Kanban, Scrum, os dois misturados e várias outras formas de desenvolvimento para milagrosamente entregar o software. Desde os anos 70 até hoje o desenvolvimento de software passou por diversas mudanças e métodos para facilitar o controle da elaboração do software, iterações, testes e entrega. Mas onde entra o código de fato e por que é tão fácil pular etapas preciosas de desenvolvimento pra tentar encaixar nos prazos? Os motivos são vários, desde falta de maturidade do time de desenvolvimento e até prazos apertados com Stakeholders esperando por milagres (o mais comum). Este último pode acontecer até mesmo por falta de habilidade/experiência com negociação.
Negociação
Nem sempre é fácil negociar prazos e as pessoas acham que todo o software é igual, se você criou uma página qualquer então toda santa página vai levar o mesmo tempo, não é isso mesmo!? Mas não é bem assim, cada empresa possui suas regras de negócios, seus nichos de clientes, expertise do tempo de desenvolvimento, cultura da empresa... Tudo isso influencia na entrega final. Mas um ponto muito importante aqui é que o desenvolvedor precisa saber NEGOCIAR. Isso mesmo, é crucial aprender a negociar qualquer entrega, prazos apertados podem criar um efeito cascata nas entregas, gerando débitos técnicos, aumento do custo para uma nova release, exaustão do time e por aí vai...
É claro que muitos custos são invisíveis e fazer entregas rápidas pode até parecer que as coisas estão indo bem. Mas nem sempre.
Quem aqui nunca desativou (ou nem fez) o pipeline de testes para entregar algo? Já fiz isso várias vezes, não me orgulho, mas foi necessário para atender algum prazo maluco. No começo pode até parecer mais rápido mas lá na frente os débitos técnicos cobram o seu preço. Problemas em produção vão surgir e mais tempo e recursos serão gastos para solucionar um determinado problema.
É claro que varia muito de entrega pra entrega, tem código que nem deveria existir mas estamos melhorando ele hehehe.
Meu ponto aqui é saber negociar, informar que um determinado prazo pode não ser cumprido, JUSTIFICANDO isso, é claro. Nada pior do que falar que algo não vai ser entregue sem ter um bom argumento. É ruim para você, para o seu time e para a empresa. Isso pode demonstrar falta de clareza com o problema/desafio que você está enfrentando. Existem entregas que realmente não sabemos o prazo mas a justificativa pra isso existe, como um exemplo: "aprender uma nova tecnologia". É normal pedir um prazo pra isso (ficar sem tempo definido vai só fazer que a curva do tempo aumente, o ser humano sempre vai preencher todo o tempo que lhe for entregue, Lei de Parkison) e pode ser que o prazo não foi o suficiente, pra isso cabe justificativa, nada mais que isso.
Entendo que muitos prazos são apertados, já trabalhei em vários projetos de madrugada, virando noites pra cumprir com a demanda. Muitas das vezes foge do nosso escopo defender que precisamos de mais tempo, pessoas que estão acima na hierarquia na empresa já podem ter vendido que o prazo é X e pronto. Gosto muito de brincar nas plannings quando algum PM/PO pergunta o prazo pra entregar algo, "pode escolher o tempo que for, desde que entrega em tal dia hehehe". É triste mas é verdade.
Mas se muitas das vezes o prazo já é algo top down onde entra a negociação? Aqui é importante para estabelecer limites e expectativas. Por mais que o meu cliente/dono da empresa/gerente ou o que for sonhe com um prazo que não é realista então ele deve estar muito ciente. Negociei isso. Nem sempre vai ser fácil e muitos não vão ficar felizes com a resposta, mas é melhor ser claro e direto do que se comprometer com algo que não é possível.
Muitas das vezes desenvolver algo com uma arquitetura X, tecnologia Y e funcionalidades N podem levar um tempo maior, então negocie algo diferente, que seja possível de entregar, para satisfazer uma determinada demanda. Pode ser que é necessário ganhar tempo para uma feature maior. Isso é muito valioso e já fiz diversas vezes. Sabe aquela entrega mais simples que depois vamos melhorar? Pois é, ela vai pra produção, resolve o problema e vamos adiante.
Isso pode ser importante em alguns casos, para startups, validar um produto, MVP, teste rápido ou o que for, mas é necessário cautela para não virar o padrão. Lembre-se, entregas rápidas e mal feitas podem gerar uma grande dor de cabeça. Sistemas mal projetados costumam parecer bonitos e robustos no começo, mas quando você precisar escalá-los você vai ver que construiu uma casa de palha e que no primeiro vento ela vai ruir.
O mundo não é um mar de rosas, mas tente ao máximo negociar prazos realistas, entregas realistas e que consigam satisfazer os dois lados. Essa é uma habilidade crucial para a evolução na carreira e que muita das vezes não é compreendida ou trabalhada.
É fácil desenvolver sistemas, o difícil é criar algo que escale.
Impactos de um código que não escala
Como já falei anteriormente, código frágil pode gerar problemas futuros. Não sou eu que está dizendo isso, é a industria de software. Aqui alguns pontos que o código frágil pode acarretar:
- Reduzir a manutenabilidade e escala: código frágil tende a ser difícil de ser alterado, de entender, de evoluir. Nada pior do que abrir uma página sem testes, com
quilos
de linhas sem sentido e que está em produção fazendo algo só Deus sabe como. Qualquer alteração é sempre uma dor de cabeça e os bugs vem juntos; - Aumento considerável de bugs e débitos técnicos: "Vamos subir assim, depois a gente ajusta" - Mito. Nunca vamos ajustar, vamos ser tragados por outra feature maravilhosa que deve ser entregue em um prazo maluco. Com isso vão ser criados mais bugs, débitos técnicos vão aumentando, até o dia que alguém solte em alguma reunião de planejamento: "vamos ter que refatorar tudo". E lá se vai tempo e dinheiro para o espaço;
- Diminui a produtividade e eficiência: Desenvolvedores gastam um tempo considerável apenas lendo o código, seja um bom código ou código frágil, isso é fato. É claro que código frágil aumenta e muito o tempo de leitura e entendimento, isso reduz consideravelmente a produtividade. Com isso o tempo para desenvolver algo começa a cair e pequenas funcionalidades são mais lentas e o código fica cada vez mais difícil de mexer, e até da medo de subir algo.
- Aumenta o custo e o risco: Esse é pouco falado porque às vezes não é muito claro pro time de engenharia e nem mesmo é passado com tanta clareza. Mas são custos "invisíveis" no desenvolvimento de software o impacto que um código frágil tem para o sistema. Correção de bugs, retrabalho, manutenção, estabilidade do sistema, segurança, efeitos colaterais, confiança e por aí vai.
Aqui um gráfico do ciclo de vida de software e o aumento do custo para realizar pequenas novas entregas:

Referência: https://diego-pacheco.blogspot.com/2020/06/software-architecture-hidden-costs.html
Como você pode verificar, mudanças no início são mais fáceis e mais baratas, com o tempo isso vai ficando mais caro e mais difícil. Agora imagine isso com um código não tão bem elaborado, isso só agrava.
Perda de oportunidade por aumentar o custo
Quando o custo de manutenção e evolução do sistema começa a crescer descontroladamente, uma consequência direta é a perda de oportunidade de inovar. Projetos que poderiam ser colocados em produção rapidamente acabam sendo engolidos por problemas técnicos, refatorações constantes, bugs inesperados e baixa previsibilidade.
O tempo que deveria ser usado para entregar valor ao negócio está sendo usado para "apagar incêndio". E isso, a longo prazo, faz com que empresas percam espaço no mercado, atrasem lançamentos estratégicos e deixem de aproveitar tendências.
A cada sprint travada por problemas arquiteturais, uma oportunidade de mercado pode estar sendo perdida.
Por que o preço do código aumenta?
O preço do código aumenta por uma série de fatores acumulativos, muitos deles invisíveis no curto prazo:
- Complexidade acidental: a solução se torna mais complicada do que o necessário.
- Alta dependência entre módulos (acoplamento): qualquer alteração gera efeitos colaterais inesperados.
- Falta de testes automatizados: o time perde confiança ao fazer mudanças.
- Re-trabalho constante: funcionalidades mal implementadas voltam para a esteira.
- Rotatividade do time: sem uma arquitetura clara, o ramp-up de novos devs é lento.
Além disso, existe um fenômeno muito conhecido chamado de “custo da mudança”: quanto mais tempo passa, mais caro é alterar o que já foi construído. Isso está bem ilustrado no gráfico que você colocou sobre o ciclo de vida do software.
Formas de evitar que a curva aumente
Evitar que a curva de custo cresça de forma exponencial envolve boas práticas técnicas, alinhamento do time e disciplina de execução. Algumas ações fundamentais:
- Defina uma boa arquitetura desde o início, mesmo que seja simples. Evoluir algo bem estruturado é mais fácil do que refatorar o caos.
- Tenha uma cobertura mínima de testes automatizados (unitários e de integração). Isso garante confiança nas mudanças.
- Organize seu projeto em domínios ou features, separando responsabilidades (ex: Feature Sliced Design, DDD, Modularidade).
- Documente o mínimo necessário: um bom README, uma estrutura padronizada e padrões de pull request já ajudam bastante.
- Reforce rituais de revisão (code review, pair programming) com foco em clareza e boas práticas.
A ideia não é engessar o desenvolvimento, mas sim criar uma base sólida que facilite o crescimento da aplicação e do time.
Como mitigar o impacto de código frágil
Se o sistema já está com uma base frágil, ainda é possível corrigir a rota — mesmo que gradualmente. Algumas estratégias para isso:
- Refatoração progressiva: sempre que for alterar um módulo ou criar uma nova funcionalidade, aproveite para melhorar o que está ao redor.
- Testes como escudo: antes de mexer em partes críticas, escreva testes que descrevam o comportamento atual. Isso te protege contra efeitos colaterais.
- Mapeie os pontos mais críticos: identifique os arquivos/pedaços de código que mais geram bugs ou retrabalho e priorize refatorá-los.
- Compartilhe conhecimento dentro do time: documente decisões arquiteturais e explique a importância de padrões adotados.
- Crie guidelines de desenvolvimento: ajude o time a entender o que é um “código bom” dentro do contexto da empresa.
Lembre-se: você não precisa consertar tudo de uma vez. Mas precisa começar.
Conclusão
Martin Fowler defende que arquitetura de software é mais sobre decisões difíceis de mudar do que sobre diagramas. Por isso, é essencial definir desde cedo o que será considerado núcleo da aplicação e o que pode ser adaptável.
Segundo o relatório do Consortium for IT Software Quality (CISQ), a má qualidade de software custou 2.41 trilhões de dólares aos EUA em 2022. E segundo o CHAOS Report do Standish Group, apenas 31% dos projetos de software são entregues no prazo e dentro do orçamento — sendo o código ruim um dos principais fatores para isso.
Referência: https://www.sonarsource.com/blog/the-true-cost-of-bad-code-in-software-development/
Criar software é uma maratona, não uma corrida de 100 metros. A arquitetura que você define hoje será o solo onde seu time vai caminhar amanhã. Cuide bem desse terreno.
Invista em boas práticas desde o início, negocie prazos com inteligência, evite atalhos perigosos e pense na escalabilidade como uma peça estratégica do seu produto. A boa arquitetura é invisível para o usuário, mas vital para o time de desenvolvimento. E lembre-se: nem todo código é urgente, mas todo código mal elaborado cobra seu preço.
Se você se viu em alguns dos cenários que descrevi, saiba que não está sozinho. Crescer como desenvolvedor é justamente isso: reconhecer, ajustar e seguir evoluindo.
Existem outros pontos que podem levar a projetos mal elaborados, como tasks mal escritas/pensadadas. Mas aí já é tema para outro artigo, eu quis trazer a visão aqui do lado do desenvolvedor de software.
Tenho outros artigos relacionados a arquitetura de software e delivery:
Referências:
- https://www.sonarsource.com/blog/unraveling-the-costs-of-bad-code-in-software-development/
- https://agilemodeling.com/essays/costofchange.htm
- https://www.ciodive.com/news/software-quality-issues-cost-IT/640268/
- https://diego-pacheco.blogspot.com/2020/06/software-architecture-hidden-costs.html
- https://martinfowler.com/architecture/
- https://www.linkedin.com/pulse/bad-software-architecture-why-my-developers-spending-more-tom-colvin/
- https://feature-sliced.design/docs/get-started/overview
- https://medium.com/@harutyunabgaryann/building-scalable-react-applications-with-feature-based-architecture-41219d5549df
- https://thetshaped.dev/p/10-ways-organize-and-design-react-application?ref=dailydev
- https://dev.to/pramod_boda/recommended-folder-structure-for-react-2025-48mc?ref=dailydev