O objetivo de refatorar e reescrever é "limpar" o sistema melhorando a legibilidde, estrutura e a clareza do código. Um código limpo erá mais fácil de manter e melhorar. No entanto, em muitas ocasiões as equipes gastam um certo tempo decidindo entre as duas abordagens.
Michael Dubakov sugere as seguintes razões pelas quais o código deteriora ao longo do tempo:
- Mais e mais funcionalidades. Isso leva ao aumento da complexidade.
- Atalhos e improvisações para suportar coisas do tipo "Precisamos dessa tela de pesquisa até Agosto. E ponto final!"
- Rotatividade. Os novos desenvolvedores não conhecem todas as decisões e ideias fundamentais que estão por trás da arquitetura. Inevitavelmente, o conhecimento se perde na trasição.
- Crescimento da Equipe. Mais pessoas, menos comunicação. Menos comunicação, más decisões.
Michael sugere que apesar de refatorar e reescrever levarem a um código mais limpo, ambas as técnicas levam o caos ao sistema existente. Refatorar é uma atividade incremental, visto que ela toca apenas numa parte do sistema de cada vez. Isso cria caos a nível local, que pode ser facilmente contido. Por outro lado, reescrever é uma mudança mais invasiva, resultando num grande caos no sistema. Devido ao seu maior impacto, o período de estabilização da reescrita e muito maior que o da refatoração.
Temos o sistema antigo durante a reescrita, portanto o caos é constante. Depois da "release", o caos aumenta significativamente. Muitos novos (e velhos) erros e comportamentos estranhos são esperados e assim o período de estabilização é maior.
Peter Schuh sugere que algumas vezes as equipes usam essas palavras de forma trocada resultando em mais confusão e caos. As equipes devem entender que reescrever é uma proposição mais arriscada quando comparada com refatorar e sendo assim devem utilizar a terminologia correta. De acordo com ele,
É apenas semântica. Bem, é apenas semântica até alguém se machucar! Reescrever código é uma empreitada arriscada e algumas vezes dolorosa. Nem sempre termina bem. Se executamos uma reescrita, mas chamamos isso de refatorar e as coisa não ficarem "redondinhas", nenhum usuário vai parar para pensar em semântica. Eles apenas vão se assustar a próxima vez que ouvirem a palavra refatorar.
Guido A.J. Stevens faz uma interessante observação. Ele sugere que a questão não é escolher entre refatorar e reescrever mas sim entre ou: refatorar, ou então: reescrever E refatorar. Ele sugere que mesmo quando a equipe decide reescrever, eventualmente eles terão dois sistemas rodando em paralelo. O sistema antigo, que pode requerer refatoração e o novo sistema que está sendo reescrito. Essa combinação gera uma tarefa extremamente complexa. De acordo com ele,
Manter uma base de código que está envelhecendo, e escrever um novo sistema, pode sugar seus recursos. Sua equipe fica dividida e vai encorrer em atrasos. Você tem que planejar e executar cuidadosamente a transição. Enquanto isso, seus competidores, não tendo o problema do curto tempo pra por o produto no mercado, vão tentar tomar seus clientes. Se você mantiver essa realidade em vista e ainda apostar na reescrita, você tem chance de ser bem sucedido.
Naresh Jain tem as seguintes sugestões especificamente para código legado.Refatorar quando o código é difícil de entender e a equipe não tem certeza do que ele faz. Reescrever quando é claro o que o código faz, mas é difícil de entender.
Assim, refatorar é a maneira preferida de melhorar o sistema de maneira incremental. Ela se dá em passos lentos, aumenta a qualidade com pequenas e constantes melhorias. Reescrever tem suas vantagens, mas em muitas situações é uma opção mais arriscada e as equipes nunca têm certeza do resultado. Como sugere Joel on Software,
É importante lembrar que quando se começa do zero não há absolutamente nenhuma razão para acreditar que você fará um trabalho melhor do que da primeira vez.