O desenvolvimento iterativo e o design ajudam você a alcançar o seu caminho para entender o que o cliente realmente precisa, para experimentar novas ideias, avaliar projetos, experimentar, responder a comentários e reagir a mudanças de circunstâncias. Tudo fica melhor quando você aprende mais sobre o domínio, o cliente, a linguagem e as tecnologias que você está usando. Isso é importante no início do desenvolvimento, e também mais tarde, à medida que o produto amadurece e na manutenção, onde você está constantemente ajustando e consertando coisas e lidando com exceções.
Mas há desvantagens também. O desenvolvimento iterativo corrói a estrutura de código e a qualidade. Michael Feathers, que vem estudando diferentes bases de código ao longo do tempo, descobriu que as alterações feitas iterativamente ao código tendem mais para a estrutura existente do código, e que os desenvolvedores fazem mais compromissos de trabalho dessa forma. Módulos de código que são alterados com frequência ficam maiores, mais gordos e mais difíceis de entender.
Trabalhando de forma iterativa, você vai acabar passando pelo mesmo ponto e constantemente revendo decisões anteriores e designs, mudando o mesmo código várias vezes. Você está fazendo progresso – se a mudança é um avanço – mas não é linear e não é limpo. Você não está indo em direção clara para a “resposta certa”, porque nem sempre há uma resposta certa. Às vezes, você retrocede ou fica em círculos, testando variantes de velhas ideias e, em seguida, as rejeita novamente, ou apenas pensa sobre um problema até que alguma solução apareça. E então alguém novo chega e não entende ou não gosta do projeto, tenta outra coisa, e o deixa para a próximo pessoa. Mudanças no design, falsos começos, becos sem saída e reviravoltas deixam rastros no código. Mesmo com refatoração constante e disciplinada, o design não será tão limpo e tão simples como seria se “desse certo na primeira vez”.
Ele não apenas desgasta o código, mas a equipe também
O desenvolvimento iterativo também tem um efeito erosivo sobre a memória de uma organização – sobre o entendimento de cada um sobre o design e como funciona o sistema. Para as pessoas que passaram por muitas mudanças de direção, modificações nas prioridades e monitoramento do que passou, é difícil lembrar o que mudou e quando, o que foi decidido e por quê, quais opções de design foram consideradas e por que elas foram rejeitadas antes, quais exceções e limites surgiram que precisavam ser resolvidos mais tarde, e o que você precisa saber quando você está tentando solucionar um problema, corrigir um bug ou fazer outra mudança no projeto.
Ao longo dos últimos seis anos ou mais, nós mudamos algumas ideias e algumas partes do código uma dúzia de vezes, ou até mesmo dezenas de vezes, às vezes de forma pequena e sutil, mas importante, e às vezes de forma fundamental. Nomes permanecem os mesmos, mas eles não significam o que eles fazem.
O acúmulo de todas essas decisões e alterações no design concepção e na direção diluem as coisas. A maioria das pessoas pode acompanhar as principais histórias, os principais caminhos bem utilizados através do sistema. Mas é fácil para as pessoas inteligentes que conhecem o design e o código perderem o controle de detalhes, dos caminhos de exceção e das dependências; as coisas nem-sempre-lógicas foram feitas para um cliente importante porque 25 ou 50 ou 110 lançamentos atrás. Isso fica ainda mais confuso quando as mudanças são lançadas de forma incremental, ou ligando e desligando em testes A/B, de modo que o sistema se comporta de forma diferente para clientes distintos em diferentes momentos.
As pessoas se esquecem ou se lembram incorretamente das coisas, fazem suposições erradas. É difícil resolver problemas no sistema, para entender quando um problema foi introduzido e por quê, especialmente quando você precisa voltar e recriar um problema que aconteceu no passado. Ou quando você está fazendo a análise de tendências e tentando entender por que o comportamento do usuário mudou ao longo do tempo – como exatamente o sistema funcionava na época? Testadores não encontram bugs, porque eles não são claros sobre o impacto de uma mudança, e as pessoas relatam bugs – e às vezes até mesmo corrigem os bugs – que não são bugs; elas apenas se esqueceram do que deve acontecer em um caso específico.
Ao fazer alterações de forma iterativa e incremental, as pessoas se concentram principalmente na mudança em que elas estão trabalhando agora, e se esquecem ou não se preocupam em considerar as modificações que já foram feitas. Um desenvolvedor pensa que sabe como as coisas funcionam porque ele trabalhou nesse código antes, mas ele esquece ou não sabe sobre uma exceção que foi adicionada no passado. Um testador entende o que precisa ser testado com base no que acaba de ser mudado, mas não pode acompanhar todos os detalhes de compatibilidade e de regressão que também precisam ser verificados.
Você acaba dependendo muito de sua suíte de testes de regressão para capturar a correta compreensão de como o sistema realmente funciona, incluindo os casos limites, e para pegar descuidos e erros de regressão, quando alguém faz uma correção ou uma mudança. Mas isso significa que você tem que depender das pessoas que escreveram e mantiveram os testes, e de sua compreensão e memória de como as coisas funcionam e qual o impacto que cada alteração teve.
O desenvolvimento iterativo vem com custos
Não é apenas o ritmo constante, a sensação de estar sempre ligado, sempre voltado para um prazo que coloca as pessoas para baixo ao longo do tempo. É também a velocidade das mudanças, o acúmulo constante de pequenas decisões, e reverter ou alterar as decisões mais de uma vez, que desgastam a compreensão das pessoas, o modelo mental que todo mundo tem de como o sistema funciona e como os detalhes são interligados. Tudo isso afeta a precisão e a eficiência das pessoas, e sua confiança.
Não tenho certeza de que há uma maneira de evitar isso. Sistemas, equipes, pessoas de todas as idades e, tal como na vida real, é natural que as pessoas vão esquecer as coisas. Quanto mais mudanças você fizer, mais chances existem de você esquecer alguma coisa.
Anotar as coisas não ajuda muito aqui. Os detalhes podem ser encontrados em algum lugar, se você olhar: no histórico de revisão, na documentação, na suíte de teste e no código. O problema é mais com a forma como as pessoas pensam que o sistema funciona do que com a forma como o sistema funciona de verdade; com a quantidade de mudanças que as pessoas podem acompanhar, podem “gravar em suas cabeças”, e como isso afeta a maneira como elas pensam e o modo como elas funcionam.
Quando você vir as pessoas perdendo a noção das coisas, ficando confusas ou cometendo erros, você precisa desacelerar, rever e redefinir. Certifique-se de que, antes de as pessoas tentarem corrigir ou alterar algo, elas tenham uma sólida compreensão do projeto maior – que elas não estão apenas focando no problema específico que estão tentando resolver. Duas cabeças pensam melhor que uma nesses casos. Junte pessoas: especialmente desenvolvedores e testadores, para se certificar de que eles têm uma compreensão consistente do que a mudança envolve. Design e revisões de código também, para ter certeza de que você não está confiando demais na memória e na compreensão de uma pessoa. Assim como na vida real, à medida que envelhecemos, precisamos apoiar-nos uns aos outros um pouco mais.
***
Artigo traduzido pela Redação iMasters, com autorização do autor. Publicado originalmente em ttp://swreflections.blogspot.com.br/2013/07/agile-development-leads-to-alzheimers.html