Muitas das outras respostas abordam problemas maiores de design ou são bastante abstratas. Se você pensar em termos do que acontecerá no futuro, poderá definir algumas técnicas claras para ajudar a proteger o código no futuro .
Pense principalmente que no futuro alguém tentará adicionar um recurso ao código ou tentará reutilizá-lo em outro lugar. Eles também podem tentar corrigir um recurso no código. Obviamente, apenas ter um bom código limpo é um ponto de partida necessário, mas também existem algumas técnicas específicas que podem ser feitas.
Programação defensiva : faça a verificação de entrada além do que o aplicativo atual realmente precisa. Sempre que você chamar APIs, verifique se a entrada deles é algo que você esperaria. No futuro, as pessoas estarão misturando novas versões de código, para que o escopo de erros e retornos da API mude do que é agora.
Elimine o comportamento indefinido : Muitos códigos possuem comportamentos que meio que evoluem do nada. Certas combinações de entrada levam a uma saída que ninguém realmente pretendia, mas acontece. Agora, inevitavelmente, alguém confiará nesse comportamento, mas ninguém o saberá, pois não está definido. Qualquer pessoa que tente mudar o comportamento no futuro quebrará inadvertidamente as coisas. Use as verificações de segurança agora e tente remover / bloquear todos os usos indefinidos do código.
Conjunto de testes automatizados : Tenho certeza de que você pode encontrar volumes escritos sobre a necessidade de testes de unidade. Em referência a provas futuras, no entanto, este é um ponto crítico para permitir que alguém refatore o código. A refatoração é essencial para manter o código limpo, mas se não houver um bom conjunto de testes, você não poderá refatorar com segurança.
Isolamento e Segregação : Encapsulamento e modularização adequada são um bom princípio de design, mas você precisa ir além disso. Você encontrará muitas vezes que precisa usar uma biblioteca, API ou produto, que pode ter um futuro questionável. Talvez devido a preocupações com a qualidade, problemas de licenciamento ou desenvolvimento contínuo pelos autores. Nesses casos, tire um tempo extra para colocar uma camada entre você e esse código. Corte a API exatamente do que você precisa, para que o acoplamento seja muito baixo para permitir uma substituição mais fácil no futuro.