Na verdade, passei por uma refatoração bastante significativa três vezes na minha carreira. O código tende a deteriorar-se, portanto, se sua base de códigos tiver tempo suficiente, um grande refator é praticamente inevitável. Todos os meus exemplos foram baseados em códigos privados, o que pode explicar por que exemplos públicos são difíceis de encontrar.
A primeira vez foi um aplicativo que, acredite ou não, tinha uma arquitetura fundamental que o fazia funcionar apenas com impressoras matriciais. Quando minha empresa não conseguiu mais encontrar um fornecedor para fornecer as fitas, eles me designaram para fazê-lo funcionar com uma impressora a laser.
A segunda vez foi uma migração de várias centenas de scripts de teste automatizados de C para Java, em parte porque precisávamos de melhor capacidade entre plataformas e em parte porque estava ficando difícil contratar novos desenvolvedores em C.
Na terceira vez, ainda estou no meio, que está modularizando uma enorme aplicação monolítica para permitir testes de unidade, reduzindo o acoplamento, e para fins de plataforma cruzada.
Eu comparo o esforço de escalar uma montanha. Você tem esse grande objetivo pela frente, mas não o atinge no nível macro. Você o segura um punho de cada vez, sempre com uma posição de segurança próxima, nunca desconectando a segurança anterior até que a próxima esteja em vigor. Você começa apenas fazendo pequenas melhorias incrementais, e depois de um tempo você se vira e de repente há essa bela vista.
Digamos que você tenha 60.000 arquivos de código altamente acoplado, por exemplo. Você quer começar a colocá-lo em teste de unidade, mas as dependências tornam isso impossível. Como você corrige isso? Você desacopla um arquivo. Você adiciona testes automatizados. Você volta ao solo estável antes de seguir em frente. Repita 59.999 vezes.
Se isso parece simples, é porque é simples. Não é fácil, mas é simples. É difícil perceber qualquer progresso no início. Faltamos dois anos para o que parecia um refatorado impossível e provavelmente ainda temos anos pela frente até terminarmos, mas, olhando para trás, de repente percebemos o quão melhor o código já ficou, e conseguimos continuar oferecendo novas funcionalidades para nossos clientes nesse meio tempo.
As outras duas vezes funcionaram da mesma maneira. Você encontra a menor etapa segura que pode executar, e sempre a mantém em um estado de funcionamento. Você só se preocupa com o cenário geral para ter certeza de que está indo na direção certa. Todas as suas ações são pequenas, constantes e incrementais.