Os 3 Vieses Do Desenvolvimento De

No meu último post, falei sobre como o hábito de dividir o software em camadas pode nos levar a trabalhar em uma camada de cada vez, produzindo o indesejado efeito BDUF (Big Design Upfront). Desta vez, vamos falar sobre como um fluxo imaginário do usuário pode nos levar a seguir cegamente um fluxo de desenvolvimento predefinido.

Entendendo o Viés da Cronologia

Lembro da primeira vez que joguei Mario Bros no console NES que meu pai me deu quando eu tinha 4 anos: o controle retangular absurdamente não ergonômico, a alegria de jogar um jogo com um personagem que tinha o mesmo nome que eu… Foi incrível!

O jogo era muito linear: 8 mundos com 4 fases cada. Você começa na Fase 1-1 e termina o jogo depois de vencer a fase 8-4. Existiam atalhos que eu podia pegar para pular algumas fases, mas eu nunca podia voltar para jogar uma fase já terminada.

Image

O mundo 1-1 do primeiro Mario Bros resumido em uma imagem

Desenvolver software sob um Viés de Cronologia é como jogar aquele jogo do Mario Bros, exceto que não é tão divertido. Você começa desenvolvendo o mundo 1-1 porque é o que o usuário jogará primeiro. Depois desenvolve o mundo 1-2, e assim por diante. Se seguirmos esse caminho, claramente não estamos caindo no Viés da Estratificação , porque estamos criando todas as camadas para cada fase (não estamos terminando o design de todos os níveis antes de implementar o mecanismo do jogo, por exemplo). Com isso poderíamos coletar feedback do cliente após desenvolver cada fase e usar isso para criar melhores fases no futuro. Mas ainda assim… estamos perdendo algumas boas oportunidades.

Sabe o que é engraçado? Essa progressão linear estilo Mario aparece em todo lugar no desenvolvimento de software. Pegue a tela de login, por exemplo - ela praticamente se tornou nossa “Fase 1-1”. É quase como se houvesse uma regra não escrita que diz “Implementarás a autenticação primeiro “ só porque é a primeira coisa que os usuários veem. E na maioria das vezes, esta é a primeira coisa que uma equipe de desenvolvimento de software implementa quando começa a desenvolver um novo produto. Você já fez isso? Eu fiz, inúmeras vezes.

Mas qual é o problema dessa abordagem?

Problemas, eu diria. No plural.

O mais óbvio é que não estamos nos beneficiando totalmente de uma abordagem ágil se estamos seguindo um caminho predefinido. Depois de revisar a Fase 1-1, teremos alguma flexibilidade sobre como desenvolver a fase 1-2, mas não sobre o que devemos desenvolver em nossa próxima iteração. Além disso, todas as nossas conversas sobre o produto deixarão aquele gosto amargo de tempo perdido porque o caminho já está definido. Esse sentimento é bastante comum entre desenvolvedores em Times Scrum durante o Planning e a Review quando estão caindo neste viés.

E se a fase 6-2 for a mais valiosa para meu usuário? Eles terão que esperar 26 iterações para finalmente poder jogá-la!

Outro problema será a mitigação de riscos. Se estou construindo um jogo do Mario, talvez eu tenha algumas ideias ousadas que quero validar primeiro, como um mundo aquático, um castelo com quebra-cabeças ou um chefe muito desafiador. Até mesmo o chefe final!

Então a solução parece direta: basta desenvolver recursos em qualquer ordem que forneça mais valor, certo? Poderíamos construir a fase 4-3 antes da fase 1-2, seguindo as prioridades do usuário em vez da ordem sequencial.

Bem… acontece que frequentemente esbarramos em um obstáculo familiar: dependências. Mas é aqui que outro clássico dos games nos oferece uma alternativa iluminadora…

Quebrando o Viés da Cronologia (e as dependências)

Voltando à minha infância e meu console NES, havia um jogo que eu amava ainda mais que Mario Bros: MegaMan. Em todo jogo do MegaMan você podia selecionar qual fase queria jogar, e uma vez que você derrotava o chefe da fase, você ganhava acesso à sua arma e podia usá-la pelo resto do jogo.

Image

Só de ver essa tela eu tenho vontade de jogar Megaman novamente!

Então, você podia escolher lutar contra o Fireman primeiro e usar sua arma de fogo contra o Iceman, ou o contrário. Depende de você. Não havia absolutamente nenhuma sequência predefinida. Mas… o que acontece se tentarmos usar a mesma abordagem no desenvolvimento de software? Bem, às vezes vamos ouvir e dizer coisas como:

Não podemos desenvolver um relatório sem criar um CRUD para inserir os dados primeiro, afinal não existe relatório sem dados!

Ok, vamos desafiar isso: Como poderíamos desenvolver um relatório sem ter uma interface para inserção de dados? Bem, mockando os dados. Imagine que vamos construir um jogo da Forca. Alguém poderia dizer que a primeira coisa que precisamos fazer é criar um dicionário de palavras que podemos usar durante o jogo, porque ter uma palavra para jogar é um pré-requisito!

Então, se cairmos nessa armadilha, provavelmente vamos gastar algum tempo desenvolvendo algo como:

Image

Não parece muito, mas requereu algum tempo para pesquisar uma maneira de gerar uma palavra aleatória, ler a documentação da API, criar uma conta, obter uma chave de API, escrever o código, testá-lo e refatorá-lo um pouco. Mas o mecanismo do jogo é muito mais importante, e se pudéssemos economizar algum tempo aqui, poderíamos usar esse tempo para desenvolvê-lo melhor. E uma maneira de fazer isso é estabelecendo uma interface simples.

Quando eu chamo a função get_word, recebo uma palavra, e não me importo realmente de onde ela veio. Se fizermos isso, poderíamos criar nosso Dicionário assim:

Image

Sim, a palavra sempre será ELEFANTE.

Mas não estou dizendo que devemos lançar o jogo assim! Tudo que estou dizendo é que agora, em vez de mostrar ao usuário uma tela que gera um monte de palavras aleatórias, vamos mostrar um jogo da Forca totalmente funcional que sempre usa a palavra ELEFANTE. E fazendo isso, nossa revisão do produto se tornará mais interessante porque agora temos uma pergunta muito poderosa para fazer: O que devemos fazer a seguir?

Poderíamos decidir implementar o Dicionário, ou o cliente poderia pedir outra coisa, como um sistema de pontuação para o jogo ou um mecanismo de dicas. Teremos opções. Não estamos jogando Mario Bros, estamos jogando MegaMan.

E como começo a fazer isso?

Antes de qualquer coisa, liste todas as suas suposições de dependência e comece a questioná-las. Eu gosto de usar a construção “Como poderíamos / sem “ para fazer isso:

  • Como poderíamos autenticar o usuário sem uma tela de login?

  • Como poderíamos gerar um relatório sem ter uma maneira de popular o banco de dados?

  • Como poderíamos mostrar esta informação sem usar gráficos?

Segundo e mais importante: certifique-se de que sua equipe sabe trabalhar com interfaces. Isso é fundamental para evitar retrabalho e quebrar coisas.

Lembre-se: para nos adaptar às mudanças com sucesso, devemos aprender a fazer isso sem aumentar os custos de desenvolvimento. Assim como no MegaMan, o melhor caminho nem sempre é o mais óbvio - às vezes você precisa lutar contra o Fireman antes do Iceman, e às vezes você precisa construir aquele sistema de pontuação antes de implementar o algoritmo perfeito de seleção de palavras.

O Viés da Cronologia, assim como seu primo o Viés da Estratificação, nos engana a seguir um caminho predeterminado quando deveríamos estar nos perguntando aquela simples mas poderosa questão: “O que devemos fazer a seguir? “. Afinal, desenvolvimento de software não é sobre completar níveis em uma ordem predefinida - é sobre criar valor da maneira mais efetiva possível.

Em breve teremos o post final desta série, onde exploraremos nosso último viés: a Modularidade.

Ah! E se você chegou até aqui, obrigado por ler!

Os 3 Vieses Do Desenvolvimento De
Os 3 Vieses Do Desenvolvimento De