Mark Christian e Johnny Rodgers publicaram recentemente no blog Slack Engineering sobre como o Slack reconstruiu com sucesso sua versão desktop. O artigo cita uma estratégia incremental de reescrita e lançamento como um fator chave de sucesso.
Duas décadas atrás, citando as desventuras do Netscape, Joel Spolsky, co-fundador do Stack Overflow, comentou em seu famoso ensaio "Coisas que você nunca deveria fazer" que o código de reescrita do zero é o pior erro estratégico que uma empresa de software poderia fazer. Spolsky mencionou dois problemas com a reescrita. Primeiro, a base de código existente geralmente incorpora o conhecimento obtido com dificuldade sobre casos e bugs estranhos, algo que pode ser perdido na reescrita. Segundo, as reescritas podem ser demoradas e desviar recursos que poderiam ser usados para melhorar a base de código e produtos existentes, e podem resultar na perda de marketshare desse produto para os concorrentes. Refatorar o código legado em vez de reescrevê-lo parece a opção menos arriscada para as pessoas que são avessas à reescrita.
Por outro lado, há argumentos a favor de reescritas completas. A sabedoria convencional refletida em "Se não está quebrado, não conserte" também significa que, no caso de um software que não pode mais ser desenvolvido a um custo satisfatório, uma reescrita pode ser justificada. Isso pode acontecer quando a manutenção e a inclusão de recursos na base de código herdada é proibitivamente cara ou se as opções tecnológicas anteriores não suportam os novos casos de uso. Reescrever os recursos das aplicações pode dar apoio ao aproveitar o novo esforço para construir uma aplicação inteiramente nova. Alternativamente, pode-se preferir replicar os recursos existentes do aplicativo sem adicionar novos, diminuindo o risco do projeto.
A equipe do Slack atribui o sucesso da reescrita do aplicativo para desktop ao fato de ter-se adotado uma estratégia intermediária, incremental e de reescrita. O código não foi reescrito do zero e lançado de uma só vez. O código legado e o novo código coexistiram durante o projeto de reescrita, com o novo código substituindo progressivamente o código antigo.
A estratégia do Slack envolveu a definição de uma arquitetura de destino e regras de interoperabilidade que mantinham o código antigo e o novo separados, permitindo a reutilização direcionada entre o código antigo e o novo:
(...) Introduzimos algumas regras e funções em um conceito chamado legacy-interop:
- o código antigo não pode importar diretamente o novo código: fica disponível somente o novo código que foi "exportado" para uso pelo código antigo.
- o novo código não pode importar diretamente o código antigo: fica disponível apenas o código antigo que foi "adaptado" para uso do código moderno.
A versão clássica do Slack, carregando o novo código e o código antigo, co-existiria com a versão moderna, que incluía apenas o novo código, até o momento em que a versão moderna alcançaria a paridade de recursos com a versão clássica:
(...) [Dessa forma] o código legado poderia acessar o novo código à medida que fosse modernizado, e vice-versa.
A estratégia de reescrita incremental foi associada a uma estratégia de liberação incremental. De acordo com o artigo:
A primeira peça "moderna" do aplicativo Slack foi o seletor de emojis, lançado há mais de dois anos, seguido pela barra lateral de canais, pelo painel de mensagens e por dezenas de outros recursos. (...) A liberação incremental nos permitiu (...) diminuir o risco do lançamento, minimizando a quantidade de código completamente novo que estava sendo usado por nossos clientes pela primeira vez.
Depois de usar internamente a versão moderna do aplicativo durante grande parte do ano passado, a equipe do Slack agora está pronta para lançar o novo aplicativo de desktop para os clientes.
A versão antiga para desktop apresentava uma pilha incluindo jQuery, Signals e manipulação direta de DOM no Electron. Também exibia um consumo de memória que aumentava rapidamente de acordo com o número de workspaces e demonstrava um desempenho mais baixo para grandes áreas de trabalho devido ao carregamento excessivo de dados. A versão moderna do aplicativo é criada no React e mostra um consumo de memória quase constante em relação ao número de workspaces. A nova versão também carrega dados calmamente e apresenta um perfil de desempenho melhor.