segunda-feira, 16 de novembro de 2009

Refatorar ou reescrever?

Uma situação que já presenciei algumas vezes é alguém dizendo: “devemos reescrever essa aplicação do zero”. Mas, realmente vale a pena? E quais as situações que levam a isso?

Nas situações que presenciei, normalmente haviam dois possíveis motivos: o código era muito ruim ou houve uma grande evolução tecnológica desde que a aplicação foi escrita.

Repare que ambos os motivos são de ordem tecnológica, não tendo nada a ver com o negócio em si.

Vamos reescrever!!!

Todo o desenvolvedor gosta de criar algo novo, dificilmente alguém gosta de manter um código existente e, principalmente, escrito por outros. Quando vemos um código ruim, sempre pensamos “eu poderia fazer muito melhor” e “é melhor jogar todo esse código fora e começar do zero”.

O mesmo ocorre quando uma tecnologia antiga é utilizada em um software.

Sempre temos algumas desculpas para reescrever:
  • A tecnologia atual é muito melhor;
  • Dessa vez vamos fazer bem feito, deixaremos o código correto;
  • Entendemos melhor o produto, não vamos cometer os mesmos erros;
  • Reescrever o produto vai ser rápido, afinal, todos os requisitos já foram levantados.

Mas, nem sempre é como esperamos

Certo, decidimos reescrever toda a aplicação. Vamos deixa o antigo código de lado. Utilizamos a antiga aplicação para olhar os requisitos e copiamos o funcionamento dela em uma aplicação novinha em folha.

Aos poucos alguns problemas vão surgindo. Alguns percebemos de imediato, outros só aparecem quando já é muito tarde:
  • Os requisitos estão embutidos no código fonte: mesmo que a aplicação tenha uma ótima documentação, não podemos confiar totalmente nela. Sempre há detalhes que só estão presentes na aplicação em si. Pequenas correções, algumas features e outros pequenos detalhes. Se olhamos apenas para a documentação, deixamos passar esses detalhes, e mesmo ao se basear no código fonte, certamente muitos detalhes passarão despercebidos;
  • O mundo não para de girar: enquanto a nova aplicação é escrita, a antiga continua sendo utilizada. Sempre será necessário incluir um novo recurso ou corrigir um bug. Nesse meio tempo, enquanto reescrevemos a aplicação, toda o desenvolvimento tem que ser duplicado, é feito na versão antiga e na nova. Além disso, evitamos adicionar qualquer recurso na versão antiga, afinal, o cliente que espere a versão nova e nela fazemos isso. Infelizmente, não é bem assim que funciona na prática;
  • Vai demorar tanto quanto a primeira versão ou ainda mais: a ilusão de que o desenvolvimento será rápido logo cai por terra. Criar uma aplicação baseando-se em outra é uma tarefa difícil, além disso, temos que manter as duas versões até que a nova esteja pronta;
  • A nova versão só poderá ser utilizada quando estiver pronta: para tirar proveito da nova aplicação precisamos esperar que ela esteja 100% concluída. Nesse meio tempo, ela não adiciona nenhum valor aos desenvolvedores e nem ao cliente. Imagine se, por algum motivo, o projeto é cancelado. Todo o código desenvolvido é perdido sem nunca ter tido nenhum valor.

Então, como fazer?

A melhor tática é refatorar a aplicação existente, fazendo ajustes de forma gradual até que todo o sistema esteja da forma que desejamos. Já escrevi a respeito de como utilizar a orientação a objetos para nos ajudar nessa refatoração (veja Parte 1, Parte 2 e Final).

Podemos alterar pequenas partes do sistema ou até mesmo jogar toda uma parte fora, porém, não o sistema inteiro.

Ao fazer ajustes graduais na aplicação evitamos toda a dor de cabeça gerada pela reescrita da aplicação inteira. É claro que normalmente é mais difícil ajustar uma aplicação do que reescrevê-la, mas no final das contas, vale a pena.

Quando reescrever?

Em algumas situações realmente vale a pena reescrever totalmente a aplicação. Uma aplicação desktop que precisa ser reescrita para web por exemplo, envolve uma mudança grande de tecnologia, nesse caso vale a pena reescreve-la totalmente.

Mesmo quando decidimos reescrever uma aplicação é recomendável ter uma estratégia de como fazer isso de forma gradual. Implementando as partes mais importantes na nova versão e deixando as duas versões viverem em conjunto enquanto essa migração é feita.

Um artigo bastante interessante escrito pelo Joel Spolsky também fala a respeito disso. Recomendo a leitura: Things You Should Never Do