Os 3 vieses do Desenvolvimento de Software - Número 3: Modularidade
Quando entendemos que o todo é a soma de suas partes, tendemos a focar em completar uma parte por vez. Mas será que sabemos tudo sobre essas partes?
O que é o viés da Modularidade?
Até agora falamos sobre Estratificação e Cronologia, e passamos da "abordagem Mario Bros" onde sempre desenvolvemos a fase 1-1 antes da fase 1-2 para a "abordagem Megaman", onde temos mais flexibilidade e podemos desenvolver nossos módulos em qualquer ordem.
Você percebeu que eu acabei de usar a palavra "módulos"? Esse é o problema que vamos abordar neste post: se consideramos que uma determinada parte do nosso software está pronta, isso significa que essa parte não é mais flexível. Se Estratificação é sobre camadas e Cronologia é sobre sequência, Modularidade é sobre as caixas onde colocamos nosso código - e às vezes, essas caixas se tornam prisões.
Entendendo o viés da Modularidade
Quando você derrota um chefe no Megaman, você ganha acesso a uma nova arma. Uma arma completa e funcional, mas também uma arma que nunca mudará. No desenvolvimento de software, no entanto, se tentarmos finalizar uma parte do nosso software e declarar que nunca mais tocaremos naquela área do código... Bom, digamos que simplesmente não funciona assim. Foi mal, Megaman.
Então, qual jogo poderíamos usar como analogia para melhorar a abordagem do MegaMan? Planescape: Torment! (Ou qualquer outro RPG clássico, na verdade).
Em Planescape, cada vez que você acumula experiência suficiente pode melhorar seu personagem adicionando pontos à sua Força, Sabedoria, Inteligência, Destreza, Carisma e Constituição. Você melhora gradualmente essas estatísticas, mas nunca completa nenhuma delas: você sempre pode adicionar mais pontos a uma determinada estatística durante seu próximo "ciclo de evolução".
Pense no Megaman: quando você começa a jogar, pode escolher uma das 8 fases para jogar. Mas cada vez que você vence uma fase, tem menos opções sobre o que jogar em seguida, até chegar a um ponto onde não terá escolha porque já venceu 7 fases e só resta uma. Você começa flexível, mas perde essa flexibilidade ao longo do caminho.
Em Planescape não adquirimos novos "módulos" para nosso personagem; melhoramos suas características de acordo com nossas necessidades, e nossas necessidades mudam conforme avançamos no jogo.
Chega de jogos. Vamos falar de software!
Bem, tecnicamente esses jogos também são software, mas eu entendi o ponto. :)
Vamos voltar ao exemplo que tínhamos no nosso último artigo: um jogo da Forca. Ao quebrar o viés da Cronologia, decidimos adiar o desenvolvimento de um "Módulo de Dicionário" implementando apenas uma função que sempre retorna a mesma palavra: ELEFANTE.
Ao fazer isso, conseguimos focar em coisas mais interessantes como o mecanismo do jogo sem gastar muito tempo com o dicionário. Se pensarmos no nosso próximo passo, alguém poderia dizer que poderíamos finalizar o dicionário real em seguida e dar ao nosso Megaman uma nova arma. Mas ao fazer isso, prejudicaríamos nossa capacidade de adaptar ao feedback do cliente, pois reduzimos a quantidade de possibilidades que poderíamos desenvolver no futuro.
A menos que estejamos dispostos a descartar parte do nosso trabalho e refazê-lo de acordo com o feedback que recebemos, é claro. Na verdade, não é um crime fazer isso, mas esse tipo de desperdício pode ser drasticamente minimizado se, em vez de implementar o Dicionário, nos fizermos a seguinte pergunta:
Como poderíamos adicionar um único ponto de melhoria em nosso Dicionário, como no jogo Planescape?
Talvez pudéssemos criar uma lista de palavras e escolher uma palavra aleatória cada vez que a função get_word
é chamada. Isso é simples, poderia ser feito em alguns minutos e melhoraria muito o jogo.
Observe que não implementamos a integração com a API mostrada inicialmente em nosso último post, mas podemos fazer isso no futuro se acharmos que é uma boa ideia.
Ou não.
Benefícios de quebrar o viés da Modularidade
Digamos que você está desenvolvendo aquele jogo da Forca usando a abordagem MegaMan e faz parte de um Time Scrum. Durante a Sprint Review, você mostra ao seu cliente o que construiu e pede feedback:
Então cliente, terminamos a Interface e o Dicionário. O que você acha que devemos fazer em seguida?
Bem, qual é o sentido de pedir feedback aqui? Se o cliente nos pedir para mudar algo relacionado ao Dicionário ou à Interface, desperdiçaremos muito do trabalho que fizemos, e se eles limitarem seu feedback às áreas restantes do software, não estamos nos beneficiando de todo o propósito do Scrum.
Agora, imagine você com a abordagem Planescape. O time melhorou nosso Dicionário e nossa Interface, mas ao invés de finalizá-los, usamos o tempo restante para criar um Sistema de Pontuação simples:
Neste cenário, você poderia fazer ao seu cliente uma pergunta diferente durante a Sprint Review, como:
Então cliente, baseado no que você viu, onde deveríamos alocar nossos próximos 3 pontos de melhoria? E o que estamos tentando alcançar fazendo isso?
Percebe a diferença? O cliente mantém suas opções e mesmo que nos peça para melhorar algo em que já trabalhamos, não jogamos trabalho fora. Pelo menos não tanto.
Além disso, talvez não precisemos implementar aquela integração com a API agora, já que o cliente decide aprimorar o Sistema de Pontuação e implementar um Mecanismo de Dicas. Enquanto isso, não teremos que nos preocupar com quantas chamadas de API estamos fazendo durante o processo de desenvolvimento, criar mocks e stubs para testar nosso jogo ou criar uma opção de configuração para tornar nosso jogo implantável em ambos os servidores de staging e produção.
O desperdício que minimizamos não está relacionado apenas ao feedback do cliente, mas a todo o processo de desenvolvimento.
Talvez nunca usemos aquela API. Na verdade, enquanto desenvolvia este Jogo da Forca para um curso de Certified Scrum Developer que eu estava dando, minha esposa jogou o jogo e teve uma ideia interessante: já que o curso era sobre Scrum, deveríamos usar palavras do Scrum Guide, e ao fazer isso acabamos com um dicionário estático que tinha 802 palavras diferentes. Todas relacionadas ao mesmo assunto: Scrum.
Como podemos evitar esse viés da Modularidade?
Vou ser direto com esta resposta: Use o Método do Hambúrguer. Eu sei que poderia elaborar mais, mas na minha experiência não há melhor maneira de lidar com esse viés como time do que usar esse método. Você pode ler mais sobre esse método aqui: https://gojko.net/2012/01/23/splitting-user-stories-the-hamburger-method/.
Também é uma ótima maneira de lidar com dependências, que frequentemente nos empurram em direção ao viés da Modularidade.
Ainda há mais uma coisa que precisamos abordar aqui: A abordagem Planescape: Torment nem mesmo é nosso destino final. Isso porque naquele jogo (que é sensacional, diga-se de passagem) sempre teremos as mesmas 6 estatísticas para melhorar nosso personagem. E se você realmente quebrar este viés da Modularidade, será capaz de descobrir novas áreas para explorar conforme avança.
Mário, você fala demais. Este post está muito longo, poderia resumir, por favor?
Sim! Antes de declarar qualquer parte do seu software como 'completa', lembre-se: até o personagem de RPG mais poderoso ainda pode evoluir.
Aqui você encontra os dois artigos anteriores sobre vieses: