Muitas vezes, os patches / changelists "complicados" são aqueles que fazem muitas coisas diferentes ao mesmo tempo. Há novo código, código excluído, código refatorado, código movido, testes expandidos; torna difícil ver o quadro geral.
Uma pista comum é que o patch é enorme, mas sua descrição é pequena: "Implemente $ FOO".
Uma maneira razoável de lidar com esse tipo de patch é pedir que ele seja dividido em uma série de partes menores e independentes. Assim como o princípio da responsabilidade única diz que uma função deve fazer apenas uma coisa, uma correção também deve se concentrar em apenas uma coisa.
Por exemplo, os primeiros patches podem conter refatorações puramente mecânicas que não fazem alterações funcionais e, em seguida, os patches finais podem se concentrar na implementação e nos testes reais de $ FOO com menos distrações e pistas falsas.
Para funcionalidade que requer muitos códigos novos, o novo código pode ser introduzido em partes testáveis que não alteram o comportamento do produto até que o último patch da série chame o novo código (um flag flip).
Quanto a isso com tato, costumo dizer que o problema é meu e depois peço a ajuda do autor: "Estou tendo problemas para acompanhar tudo o que está acontecendo aqui. Você poderia dividir esse patch em etapas menores para me ajudar a entender como isso tudo se encaixa? " Às vezes é necessário fazer sugestões específicas para as etapas menores.
Um patch tão grande como "Implement $ FOO" se transforma em uma série de patches como:
- Apresente uma nova versão do Frobnicate que usa um par de iteradores porque eu precisarei chamá-lo com sequências diferentes de vetor para implementar $ FOO.
- Altere todos os chamadores existentes do Frobnicate para usar a nova versão.
- Exclua o antigo Frobnicate.
- Frobnicate estava fazendo muito. Fatore o refrumple em seu próprio método e adicione testes para isso.
- Introduza o Zerzify, com testes. Não usado ainda, mas vou precisar dele por $ FOO.
- Implemente $ FOO em termos de Zerzify e o novo Frobnicate.
Observe que as etapas de 1 a 5 não fazem alterações funcionais no produto. Eles são triviais para revisar, incluindo garantir que você tenha todos os testes corretos. Mesmo que o passo 6 ainda seja "complicado", pelo menos ele é focado em $ FOO. E o log naturalmente dá uma idéia muito melhor de como $ FOO foi implementado (e porque Frobnicate foi alterado).