Estou procurando orientação sobre o acoplamento DRY x código. Não gosto de duplicar meu código e também não gosto de acoplamento de código entre módulos não relacionados. Portanto, refatoro o código duplicado se encontrar o código duplicado identicamente um ano após a introdução da duplicação. No entanto, tenho experimentado situações cada vez mais em que o mundo real é muito mais imprevisível e, depois de refatorar o código, surgem situações que exigem a criação do código novamente.
Por exemplo, se eu tivesse um código para lidar com carros a gasolina, SUVs a gasolina, carros elétricos e SUVs elétricos, digamos que eu refatorasse o código duplicado na hierarquia "gasolina" e na hierarquia "elétrica", ambas descendentes da hierarquia "veículo". Por enquanto, tudo bem. E então, minha empresa introduz um carro híbrido e um semi híbrido, que exigiriam alterações essenciais na minha hierarquia original. Talvez fosse necessário "composição" entre a hierarquia da gasolina e a elétrica.
Claramente, a duplicação de código é ruim porque aumenta o tempo necessário para implementar uma alteração comum a todos os produtos acima. Mas refatorar o código comum torna igualmente difícil a introdução de variações específicas do produto e leva a um grande "salto de classe" quando é preciso encontrar a linha de código para corrigir um erro - uma alteração em uma classe pai de nível superior poderia disparar erros de regressão entre todos os descendentes.
Como encontrar um equilíbrio ideal entre o acoplamento de código DRY e o indesejado?