Muitas vezes, patches / changelists "complicados" são aqueles que fazem muitas coisas diferentes ao mesmo tempo. Há um novo código, código excluído, código refatorado, código movido, testes expandidos; dificulta a visão geral.
Uma pista comum é que o patch é enorme, mas sua descrição é pequena: "Implementar $ FOO".
Uma maneira razoável de lidar com esse patch é pedir que ele seja dividido em uma série de pedaços menores e independentes. Assim como o princípio de responsabilidade única diz que uma função deve fazer apenas uma coisa, um patch deve se concentrar apenas em 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 do $ FOO com menos distrações e arenques vermelhos.
Para funcionalidades que exigem muito código novo, o novo código geralmente pode ser introduzido em partes testáveis que não alteram o comportamento do produto até que o último patch da série realmente chame o novo código (um flag flag).
Quanto a fazer isso com tato, costumo dizer que é meu problema 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 tudo isso se encaixa? juntos?" Às vezes é necessário fazer sugestões específicas para as etapas menores.
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 precisarei chamá-la com sequências diferentes de vetor para implementar $ FOO.
- Alterne todos os chamadores existentes do Frobnicate para usar a nova versão.
- Exclua o antigo Frobnicate.
- Frobnicate estava fazendo muito. Fatore a etapa de reformulação em seu próprio método e adicione testes para isso.
- Apresente o Zerzify, com testes. Ainda não usado, mas vou precisar por US $ 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 fáceis de revisar, incluindo garantir que você tenha todos os testes certos. Mesmo que a etapa 6 ainda seja "complicada", pelo menos está focada em $ FOO. E o log naturalmente dá uma idéia muito melhor de como o $ FOO foi implementado (e por que o Frobnicate foi alterado).