Vamos precisar reescrever essa aplicação do zero.

Quem nunca disse ou ouviu isso? Vamos entender os motivos por trás dessa icônica frase.

Vamos precisar reescrever essa aplicação do zero! É a frase de rendição, é sinal que as coisas foram para o caminho errado. Dias, meses, anos de desenvolvimento que serão jogados fora por falta de um bom planejamento.

Vamos precisar reescrever essa aplicação do zero.

Quando chegamos nessa situação geralmente estamos diante de alguns dos cenários a seguir:

  • A tecnologia da aplicação é antiga demais e os novos recursos demandam mais tecnologia.
  • A arquitetura da aplicação é uma engenhoca complexa e sem sentido.
  • Devido a diversas implementações e manutenções do passado feitas de forma irresponsável ou sem padrão a aplicação se tornou a famosa “colcha de retalhos”, qualquer tipo de mudança é sofrível e demorada.
  • A cada mudança surgem diversos bugs em todas as partes da aplicação, pois existe muito acoplamento entre suas divisões, “tudo está acoplado com tudo”.
  • O time que trabalha na aplicação atualmente não concorda com a forma com que foi escrita e não está satisfeito em trabalhar nela.

Algumas situações muitas vezes não possuem uma escapatória, por exemplo o envelhecimento natural da aplicação. É muito caro manter uma aplicação sempre alinhada com a última versão da tecnologia, logo, algumas vezes prefere-se optar por saltos (atualizar a cada X tempo) ou simplesmente reescreve-la depois de alguns anos.

O cenário de envelhecimento da aplicação é um dos menores, geralmente a aplicação morre muito antes da hora. Eu trabalhei em uma empresa onde assisti a mesma aplicação ser reescrita 1 vez ao ano durante 3 anos. O que ocorre de tão errado assim?

Existem muitos motivos para tudo dar errado:

  • Equipe tecnicamente despreparada.
  • Falta de um líder técnico ou arquiteto que conduza o time e evite a deformação da aplicação.
  • Escopo mal planejado, falta de entendimento da entrega.
  • Prazo mal calculado.
  • Falta de visão. Típico caso do sisteminha de cadastro que virou um “ERP”.
  • Gestor de equipe que pula etapas e/ou não valoriza (não conhece) boas práticas, impondo uma metodologia que funciona apenas na teoria dele.

Motivos para dar errado são muitos, fazer software da forma correta é infinitamente mais complexo que simplesmente entregar software. É necessário ter uma boa equipe, um bom líder e um bom gestor.

Software é um bem durável assim como uma TV, Geladeira ou Carro, paga-se muito caro para desenvolve-lo e muito caro para mante-lo. A diferença é que o software precisa ser flexível e adaptar-se às constantes mudanças de escopo, logo não pode possuir uma engenharia fechada como uma TV e geralmente é ai onde mora a maioria dos problemas.

Para garantir um bom funcionamento da aplicação de forma que ela se adapte às diversas mudanças de escopo com o mínimo de esforço necessário e sem gerar outros problemas secundários, é preciso projetar a aplicação, não basta simplesmente escrever a aplicação e entregar.

Alguns pontos importantes devem sempre ser abordados:

Processo

Processo de desenvolvimento de software é um tema extenso demais, portanto deixarei apenas alguns pontos em destaque que devem ser levados bastante em consideração.

Processo de desenvolvimento de software é um processo diferente de outros, porém infelizmente ainda existem gestores que imaginam que desenvolver uma aplicação é o mesmo que construir um prédio, um navio ou um avião.

Durante a construção de um prédio com a obra em estágio avançado é praticamente impossível aplicar mudanças que mudam o aspecto do projeto, existe uma engenharia fechada e projetada para ser daquela forma, qualquer mudança poderia impactar em ter que iniciar novamente do zero.

Uma aplicação bem projetada deve ser flexível e estar aberta para mudanças de escopo com menor esforço necessário, portanto não devemos nos apegar em simplesmente entregar o que foi inicialmente levantado.

Uma das formas mais práticas de atender a necessidade do cliente é a entrega contínua, releases parciais para acompanhamento e feedback do cliente, é muito mais fácil ajustar uma mudança de escopo com a aplicação 30% desenvolvida do que se estivesse 100%.

Focar em definir bem os requisitos das entregas mais próximas é muito melhor que tentar documentar 100% do projeto antes mesmo de iniciar a codificação.

Sim estamos falando de metodologias ágeis como o Scrum por exemplo, um projeto de software é diferente de um projeto de construção civil e merece um framework de desenvolvimento interativo e incremental.

Planejamento

É necessário analisar qual será o porte da aplicação, não existe uma receita para todo tipo de aplicação, se ela for grande e complexa é necessário abordar alguma prática de arquitetura, por exemplo DDD.

Se a aplicação for simples é necessário evitar exageros e complexidades que não beneficiam as funcionalidades da aplicação.

Orientações como o KISS e o YAGNI dizem para evitar os exageros e manter a aplicação simples, é fato, mas isso não significa que você deve fazer tudo na camada de apresentação por exemplo, uma mínima divisão de responsabilidades é essencial para a qualidade de qualquer tipo de aplicação.

Arquitetura

Arquitetura é a base de tudo, é muito importante fazer a escolha ideal e evitar a famosa “arquitetura BOLOVO” de 3 camadas (Modelo, Business e DataAccess).
Hoje em dia está claro que apesar de funcionar e ser simples esse modelo traz muitos problemas.

É muito importante ter uma pessoa no papel de arquiteto, que conheça diversas estratégias de arquitetura e saiba aplicar bem os inúmeros patterns disponíveis.

Uma vez que possui sua arquitetura definida a aplicação deve se manter dentro do aspecto da arquitetura original, corromper camadas para acessar mais facilmente o banco ou para resolver mais rapidamente um problema pode ser considerado um crime.

Descaracterizar a arquitetura de uma aplicação é o primeiro passo para a famosa “Colcha de Retalhos”. O arquiteto ou líder técnico deve ser responsável por garantir que a arquitetura não esteja sendo corrompida e que seja mantida dentro de sua proposta em toda extensão da aplicação.

Codificação

Mesmo com uma arquitetura definida a tarefa de codificação ainda é complexa e não existem motivos para ser diferente. Codificar exige muitas habilidades além do próprio conhecimento da linguagem e plataforma.

É importantíssimo valorizar os princípios básicos da orientação à objetos como o SOLID que apesar de ser básico podemos dizer que grande parte dos desenvolvedores ainda não sabem como escrever código usando injeção de dependência (DIP) para evitar o alto acoplamento. Realizam heranças sem sentido apenas pelo fato de um objeto herdar hierarquicamente de outro no mundo real. Deixam o princípio de responsabilidade única de lado (SRP) e não criam classes extensíveis (OCP) deixando o código sempre aberto.

Entre outros pontos falhos não citados, os mencionados acima já são responsáveis por grande parte dos problemas existentes em nossas aplicações. Codificar não é uma tarefa menos grandiosa como arquitetar um sistema, pelo contrário, precisamos valorizar mais o programador que possui esses conhecimentos.

Padrões de codificação como nomenclaturas e regras são importantes para manter a expressividade e facilidade de leitura do código. Antigamente programadores se gabavam por fazer códigos que somente eles entendiam, isso não deve existir, o código é uma série de instruções que devem ser de leitura clara e leve, muitas vezes dispensando uma documentação própria.

Uma técnica de codificação que vem ganhando popularidade é o TDD, apesar do TDD ter seu nome diretamente relacionado com testes o TDD na verdade é sobre codificação, os testes que guiam a codificação via TDD servem para garantir a qualidade do código que no final também garantem a sua testabilidade.

Testes

Testes é um assunto complexo, primeiramente devemos entender que teste de software não é apenas rodar a aplicação e ver se tudo está funcionando.

Existe mais de um tipo de teste, podendo ser de unidade, de integração e etc.

Os testes de unidade são necessários quase sempre, podemos dizer que 80% de cobertura de código através dos testes é um resultado bem positivo. Testes de unidade são muito importantes para garantir a boa escrita do código e validar a sua funcionalidade durante o desenvolvimento. Se durante a codificação um teste falhar pode significar que alguma coisa foi feita de forma que o código deixou de funcionar como deveria, logo evitará o deploy prematuro em produção e que o cliente tenha a infelicidade de descobrir um novo bug.

Descobrir um bug em tempo de codificação é N vezes mais barato que descobrir um bug em produção, evita retrabalho, horas extras, replanejamento de deploy, insatisfação com o cliente etc.

Muitas pessoas alegam que escrever testes de unidade fazem o software custar mais caro, pois aumenta mais o esforço de codificação. Isto parece fazer sentido se olharmos apenas no sentido da entrega, mas mesmo assim não faz. Os testes exigem mais esforço de codificação, porém conforme a cobertura de testes aumenta a velocidade de entrega aumenta junto, pois os testes facilitam muito as futuras modificações.

Contabilizar o esforço apenas baseado na entrega é uma falha. Devemos sempre levar em conta a manutenção e evolução, e quando falhamos nesse aspecto estamos iniciando o ponto onde a aplicação vai se tornar cada vez mais complexa para se testar, evoluir, receber manutenções.

Costumo dizer que programamos uma aplicação durante 6 meses e a mantemos durante 3 anos ou mais, sendo assim nosso foco deveria ser na manutenção e evolução e não apenas na entrega. Todo lucro obtido numa entrega mal planejada será perdido durante a manutenção, podendo inclusive chegar ao negativo, e esse é um dos principais motivos que levam diversos projetos falharem e se transformarem em prejuízo quando deveriam continuar gerando lucros.

Os testes de unidade são de responsabilidade do desenvolvedor, os testes de integração e etc podem ser de responsabilidade de um profissional de qualidade ou simplesmente de toda a equipe (equipes multidisciplinares sabem codificar e testar).

Testes de unidade garantem a qualidade de escrita do código e de sua funcionalidade, um código que não está coberto por testes não é um código confiável. Não existe processo ágil de desenvolvimento sem testes, portanto está claro. Testar é preciso!

Quando tudo deu errado.

O planejamento da aplicação não foi bem feito, a arquitetura não foi bem desenhada para atender o propósito da aplicação, a codificação está estruturada, acoplada e sem padrão, não existem testes de unidade e realizar qualquer manutenção significa alterar diversas partes do código e ser obrigado a testar manualmente todas funcionalidades de ponta a ponta, mesmo assim sempre escapando alguns novos bugs.

As noites são longas quando é necessária alguma manutenção, o deploy em produção é uma aventura preocupante, a satisfação de trabalhar no projeto já não existe mais e a pressão não vale a pena.

O gestor do projeto não aceita mais tantos bugs e exige mais assertividade, questionando inclusive a capacidade técnica da equipe, o cliente não aceita mais os prazos para ajustes simples e não quer pagar a mais por isso também.

Não dá mais!  Vamos precisar reescrever essa aplicação do zero.


Se você estiver interessado em conhecer mais e aprender como desenvolver aplicações Web com arquitetura baseada em DDD, aplicando os princípios SOLID, diversos Design Patterns e escrevendo testes de unidade inscreva-se em meu curso:

Vamos continuar a troca de experiências, deixe seu comentário abaixo, se gostou e concorda com o artigo compartilhe com seus colegas para transmitirmos essa mensagem para o máximo de pessoas possíveis. 😉

25 ideias sobre “Vamos precisar reescrever essa aplicação do zero.

  1. Meu caro Eduardo, hoje no meu trabalho falamos muito sobre isso.
    E até parece que você escultou as nossas conversas, pois muito do que você demonstrou, infelizmente é a realidade de várias empresas.
    Como profissional fazemos a nossa parte, mas para o sucesso do projeto TODOS pilares devem sempre estarem alinhados, porém na maioria das vezes é difícil TODOS estarem alinhados.
    No mais parabéns pelo artigo abordou muito bem os problemas de um desenvolvimento de projetos principalmente a parte da gestão.

    Forte abraço.

  2. Ola Eduardo, estou desenvolvendo na arquitetura DDD, mas recentemente entrei numa empresa que trabalha com padrão MVVM, queria saber sua opinião sobre essa arquitetura, abraços.

    • Marcelo, DDD e MVVM não se comparam, MVVM não é arquitetura, é estratégia de frontend que pode ter no backend uma arquitetura padrão DDD, assim como MVC + DDD.

      Abs!

  3. Excelente texto Eduardo. Fui seu aluno na turma de Julho deste ano, e sempre recomendo o curso a todos que trabalham comigo. Além de aprender muito sobre esses assuntos me deu um norte de estudo, e me permitiu planejar melhor minha carreira.

    Abraço!

  4. Eduardo, ótimo artigo.
    Vivi uma experiência dessas quando o Scrum Master de um projeto que participei conseguiu convencer o Product Owner do projeto patrocinar a reescrita do mesmo. Foram seis meses de definição e estudo de uma arquitetura que se adequasse ao projeto, no fim foi escolhida uma arquitetura de ncamadas baseada em DDD. O ganho na qualidade do software e no valor de negócio para o cliente foram enormes. Vejo que é uma decisão difícil, precisa de coragem e de gente comprometida, mas, é a decisão mais correta.
    Eduardo, gostaria de fazer duas perguntas:
    – Qual sua opinião sobre uma empresa utilizar-se de um framework próprio? Na verdade uma IDE que gera CRUDs básicos, relatórios…
    – Uma coisa que trabalhei durante um bom tempo, no projeto que citei acima, foram as “trilhas de desenvolvimento” onde, devido a falta de acoplamento, três desenvolvedores trabalhavam em uma mesma hitória, sendo um com application service/ view, outro no domain e o terceiro na infrascructure. Essa é uma prática muito bacana, mas vejo pouco conteúdo sobre as Trilhas na web, o que você acha da utilização dessas “Trilhas de Desenvolvimento”?

    • Muito bom esse seu feedback Juliano!

      Que sirva de motivação para os demais 🙂

      Sobre as suas perguntas:
      – Framework próprio, gerador de telas, cruds, etc… Nada pode ser pior que isso, com algumas experiências muito ruins de vivência lhe aconselho, evite framework próprio e gerador de crud.

      – É ótimo poder colocar mais de uma pessoa na mesma história, desde que valha a pena. Tem que ser benéfico 9 mulheres não geram um filho em 1 mês, logo se realmente valer a pena com certeza é uma prática que deve ser incentivada, e obviamente só será possível com um bom nível de separação de responsabilidades no código.

      Abs!

      • No momento que a empresa cria seu “framework próprio” ela não tem mais um produto. Ela tem dois. Vai chegar um momento que ela terá um time para o produto que vai pro cliente e um time para manter esse “framework próprio”, fora os problemas, custo e dependência forte disto. #medo #arrepios

        • Bom mesmo é usar framework tipo Angular, Batman né ? Que as “poderosas” simplesmente abandonam quando não é necessário mais para ela.

          Criar próprias ferramentas depende muito, de que tipo de framework está falando, e qual é o nível de abstração que terá o mesmo.

          Também deve-se olhar o time, se é capaz ou não de manter.

          Tirando isso, não vejo nenhum problema ou “medo” em criar seu próprio framework.

          • Rodrigo (sem ser o Kono), concordo muito com você. Algumas pessoas pensam que têm respostas pra tudo e acabam se enrolando no meio do assunto, falando asneira atrás de asneira.

      • Boa noite Eduardo, estudando aqui no seu site, depois de ver seu comentário acima não tive como não postar. Estou sofrendo a beça com um Framework próprio pra crud onde trabalho e somado com um wcf que não vejo uma razão se quer pra se utilizar nos projetos que trabalhamos, e com um “scrum máster” inflexível, (autor do framework). Futuro próximo? prefiro ganhar menos num lugar que se tenha mais bom senso e trabalho em equipe.

  5. PERFEITO!!! Os pontos levantados refletem a realidade! Já encontrei (e me encontrei) na situação de ver um projeto com um design ruim, querer melhorar-lo mas sem saber exatamente como, por isso artigos como esse são bons pra instruir o pessoal a desenvolver softwares de maior qualidade.

  6. Artigo bom, e é a realidade de muitos projetos, apenas tenho a minha opinião em um dos pontos que você citou, DDD

    Apenas discordo em achar que tudo na plataforma .net se resolve com DDD
    DDD é uma arquitetura complexa.

    DDD tem alguns de seus propósitos muito bom, outros não, é uma arquitetura bem válida para aplicações Desktop, na Web, acredito que deva-se pegar apenas alguns conceitos do DDD.

    É muito falado “ah, mas em projeto grande é bom usar DDD”, mas nunca se fala “qual projeto? qual é o nível ? é atividade crítica?”, são N perguntas a se fazer antes de definir uma arquitetura.

    Mas como falei, é a minha opinião, no mais concordo com todo o texto, parabéns Eduardo =)

    • Eu concordo com você Rodrigo, ja trabalhei em lugares onde haviam pessoas que achavam que eram o Deuses da arquitetura, mas nas entre linhas sempre admitiam que usam uma bazuca pra matar uma formiguinha, resultado…
      Complexidade extrema, tempo de desenvolvimento elevado, curva de aprendizado de novas pessoas na equipe muito maior do que o normal.
      Ah mas a manutenção fica mais fácil…
      Será?
      Como você disse. Quais os critérios para se escolher o DDD que também acho bem complicado?
      Porque assim como Eduardo Pires disse em um outro post que li sobre o assunto, o tema arquitetura em .net é coisa rara.
      Quais são as alternativas?

      • Olá Vagner.

        Sim, é isso mesmo que você citou, infelizmente no .net há muitas pessoas disseminando DDD de forma errada, deixando-a complicada, achando que tu se resolve com DI e Repository Pattern.

        Arquitetura em .net é raro mesmo, mas não é algo que você fale “Vamos usar arquitetura X para todos os projetos”, isso depende muito de projeto a projeto, então a arquitetura é você mesmo quem faz. E também, não há segredos. A NetFlix por exemplo, ela utiliza em seu backend Java e .Net, e lá, eles não trabalham com DDD, e aí ? O que você me diria? Olha o tamanho da plataforma e o número de acessos(requisições) que não deve ter né ?

        Uma alternativa, respondendo a sua pergunta é, tirar alguns conceitos que você acha interessante em DDD, e sempre se basear em ISP e SOLID

        • Mas pessoal. DDD são métricas que você aplica ao seu domínio de negócio para construir sua aplicação. Não faz muito sentido o que vocês falaram. DDD não é um bootstrap que vc usa ou não. O mínimo que decidir, pronto. Já está usando.

          Se vai usar DDD ou não, só vale ver se não está fazendo algo que já foi comprovado que é errado. Algo como um anti-pattern é uma lástima pra um projeto.

          Valeu moçada!

          • Rodrigo, o que falei de errado?
            DDD é uma forma de arquitetura. Aonde ela é baseada no negócio da sua aplicação(DOMAIN)

            O problema que revisei, é que muitos por aí, estão aplicando e explicando de forma complicada e as vezes até errada, deixando muito confusos devs que não tem experiência e dando a eles inúmeras camadas que eles não entendem o que se faz realmente.

            Além de alguns patterns que acham que é a resposta para tudo, a questão não é ser anti pattern, é trabalhar com os patterns corretos de acordo com o projeto.

  7. Muito bom! Obrigado!

    obs: tem um trecho do artigo “desenvolvimento interativo e incremental.”, não seria “iterativo” no lugar de “interativo”?

    • Iterativo: que serve para iterar; repetido
      Iteração: repetição
      Iterar: tornar a fazer; repetir
      Interativo: que interage; que permite comunicação em dois sentidos
      Interagir: agir mutuamente (uma entidade agindo sobre outra e vice-versa)

      Ou seja… É interativo mesmo.

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *