Sempre que ouço líderes de projeto reclamarem sobre o desenvolvimento de software utilizando cascata (waterfall), pergunto porque não tentam uma abordagem mais ágil. A resposta mais comum é que não sabem por onde começar. O fato de existirem vários livros sobre desenvolvimento ágil de software não torna as coisas mais simples. Explicar para a uma equipe de projeto que se pretende abandonar tudo o que sabem para tentar algo completamente diferente pode ser bastante difícil, e esse tipo de mudança tende a afetar o gerenciamento do projeto.
A verdade é que o desenvolvimento ágil de software é extremamente simples e altamente customizável. Pode-se começar a aplicar os princípios ágeis em qualquer ponto do seu processo de desenvolvimento e fazer as modificações ao longo do tempo até que esteja perfeito para sua equipe. Acredito nisso porque vivi na prática este processo.
Trabalho na indústria de Defesa, onde não se escreve uma linha de código enquanto não houver muita documentação sobre o software. Entretanto, mesmo nessa cultura aparentemente "não-ágil", aplicamos princípios e práticas ágeis com sucesso. Ao longo de várias entregas (ou releases), as equipes seguem um processo ágil bastante efetivo que foi customizado para o ambiente da indústria de Defesa.
O Processo
Mudança 1: Adoção do Desenvolvimento Iterativo
Os aspectos mais fundamentais no desenvolvimento ágil são a integração contínua e os testes. Os processos ágeis se empenham em entregar código mais cedo e com maior frequência, permitindo aos interessados testarem e opinarem continuamente. A entrega antecipada de código funcionando é um seguro contra o fracasso do projeto. Se quer entregar software que os consumidores adorem e que realmente utilizem, construa-o em pedaços e mostre aos consumidores o quanto antes e com frequência. Caso contrário, você pode acabar entregando o produto errado.
A adoção de um estilo de desenvolvimento iterativo foi uma grande mudança para nós, especialmente por estarmos aplicando a iteração sobre um processo que requer muita documentação inicial. Nosso processo cascata tradicional exigia que os analistas escrevessem os requisitos, que depois eram refinados em requisitos de software e que depois, finalmente, eram passados para a equipe de desenvolvimento (que não fazia parte do início do processo). Somente depois que os requisitos do software estavam finalizados e aprovados é que a equipe começaria a programar. A transição para a integração contínua foi possível convencendo a equipe de que "bom o suficiente" é melhor do que "perfeito".
Essa nova cultura permitiu a quem criava a documentação entregar, logo no início do processo, artefatos ainda preliminares para as equipes de desenvolvimento iniciarem o desenvolvimento dos primeiros protótipos. As implementações iniciais, por decorrência desta rapidez, continham falhas, mas cujo feedback fizeram com que fossem elaborados artefatos de sistemas cada vez melhores. As equipes não precisam de artefatos perfeitos para iniciar o trabalho, mas apenas de um ponto de partida e tempo suficiente para executar várias pequenas correções de curso ao longo do desenvolvimento.
Nosso primeiro passo em direção à agilidade começou convertendo em várias iterações de 8 semanas um projeto de um ano de duração que usava modelo tradicional de desenvolvimento (cascata). Esses intervalos de oito semanas, que poderiam ser chamados de "mini-cascatas", ajudaram a resolver questões e apontar problemas frequentemente esquecidos e relacionados ao custo de integração. Quando as equipes integram seus códigos apenas uma vez por release, o custo é maior, pois quase sempre requerer mais tempo do que o planejado. Devido a baixa frequência de integrações e ao fato de ser uma experiência dolorosa, tendemos a bloquear esse tipo de problema da memória e o esquecer quando chega a hora de planejar a próxima release.
Quando mudamos para um processo iterativo que tornou mensal a dolorosa experiência de integração, mostrou-se óbvio que tínhamos um problema. A cada iteração aprendemos e melhoramos até tornar a integração do software muito mais eficiente. Em nossa sexta integração já éramos duas vezes mais eficientes em termos de resolução de problemas de integração que havíamos sido no começo.
Ao longo das releases seguintes, começamos a diminuir as iterações até chegarmos em iterações de 2 semanas. A cada duas semanas, portanto, entregamos software testado e funcionando e podemos replanejar as próximas duas semanas. Durante as iterações iniciais, as equipes de análise e de desenvolvimento trabalham juntas criando requisitos, protótipos e designs - em que o trabalho de cada equipe se torna um artefato de entrada para a outra equipe. À medida que realizamos iterações, cada equipe refina seus artefatos e obtém feedback dos usuários e stakeholders. Nas iterações seguintes, os protótipos se transformam em códigos em produção e os bugs são encontrados e resolvidos a cada duas semanas junto com o desenvolvimento. Os benefícios gerais do desenvolvimento iterativo são fantásticos:
- Os analistas acabam definindo o "sistema certo" (isso é importante em Defesa);
- O desenvolvimento de software pode começar antes e contribuir para os artefatos de sistema;
- Os testadores enxergam a evolução das funcionalidades ao longo do tempo, o que lhes dá experiência e confiança para realmente encontrar bugs que não encontrariam utilizando simples testes de requisitos;
- Integração é sempre algo doloroso, porém integrar a cada duas semanas é mais gerenciável. Além disso, a integração frequente permite identificar os problemas mais cedo e consertá-los para que não ocorram na próxima iteração;
- Encontrar e corrigir bugs a cada duas semanas é muito mais fácil do que consertar bugs em um código após meses;
- Integração frequente fortalece o vínculo com a equipe de testes. Desenvolvedores e testadores trabalham juntos em vez de agir como adversários;
- Podemos adaptar e fazer mudanças de curso mais cedo quando o projeto estiver indo na direção errada.
Mudança 2: Mantenha as Tarefas Pequenas
A principal vantagem do desenvolvimento iterativo é permitir correções de direção com uma frequência maior e a habilidade de enfrentar problemas antes que se tornem grandes. Tais conceitos podem ser aplicados, inclusive, por cada pessoa, individualmente, na execução de suas tarefas diárias. Se as iterações duram 8 semanas, por exemplo, é uma boa prática não ter atividades que durem, sozinhas, 8 semanas também. O risco de não trabalhar em atividades pequenas pode ser visto somente no final da iteração e não dar tempo de corrigir eventuais problemas ou exigir ajuda de outros membros da equipe.
Após observarmos a necessidade de termos tarefas menores, para feedbacks mais frequentes, adotamos a regra de que nenhuma tarefa poderia durar mais de 40 horas. Isso significa que os desenvolvedores devem planejar seu trabalho com uma granularidade menor que 40 horas para cada tarefa. Foi uma mudança muito simples e os benefícios foram enormes. Utilizar tarefas com duração inferior a 40 horas significa que:
- A equipe produz menos código por tarefa, o que permite revisões de melhor qualidade. Por outro lado, revisar 8 semanas de código de uma só vez, resultaria, fatalmente, em mais bugs;
- Gerentes, pares, revisores de código e testadores são mais capazes de compreender o trabalhos menores, produzidos em 40 horas ou menos. Uma tarefa de 32 horas de duração, como "Disponibilizar o comparativo de propriedades alugadas visualmente no mapa", é muito mais fácil de discutir, revisar e testar do que uma tarefa de 400 horas como "Funcionalidades do Mapa";
- A equipe pode se recuperar mais facilmente de erros. Quanto menos horas de trabalho na direção errada, mais fácil será para retomar ao cominho correto.
Mudança 3: Sistema de Parceiros
Programação em pares (Pair programming), é um conceito definido na metodologia Extreme Programming (também conhecida como XP) em que dois programadores trabalham sempre juntos (na mesma tela e com o mesmo teclado). A ideia é que dois desenvolvedores se tornam mais capacitados para acertar da primeira vez, economizando tempo no ciclo de desenvolvimento. O conceito é interessante, entretanto nunca o vi sendo usado fora dos círculos acadêmicos e nunca conheci um desenvolvedor desejando voluntariamente trabalhar pareado com outro oito horas por dia, cinco dias por semana.
Ao invés de programar em pares, minhas equipes usam o "buddy system" (em tradução livre: "sistema de parceiros"). Extraímos os conceitos principais da programação em pares e os flexibilizamos para adequá-los à cultura da nossa equipe, mantendo seus benefícios. Cada desenvolvedor tem um parceiro ("buddy") que é consultado diariamente, antes de iniciar sua tarefa, sobre o problema e a abordagem que pretende conduzir para a tarefa que irá iniciar. Isso leva apenas 5 minutos e pode economizar muitas horas.
O sistema de parceiros ("buddy system") também se aplica à arquitetura e design. Na fase de design, os designers encontram seus parceiros frequentemente para discutir mudanças. Com esse processo, fomos capazes de acertar da primeira vez e reduzir significativamente a probabilidade de grandes problemas de design serem encontrados mais tarde no ciclo de desenvolvimento.
Os benefícios do sistema de parceiros incluem:
- O parceiro tem melhores condições de revisar o código porque pode compreender melhor os motivos pelo qual foi concebido;
- A discussão das soluções antes de implementá-las revela problemas e previne erros;
- Um substituto é capacitado para o caso de outro membro sair inesperadamente da equipe.
Para onde estamos indo
O processo de desenvolvimento de software continuará evoluindo na medida em que a equipe aprende mais a respeito do que funciona e do que não funciona. Nossa equipe fez muito progresso migrando do processo cascata para um processo ágil integrado e adaptativo. Ainda estamos trabalhando em algumas melhorias, como:
- Troca de requisitos tradicionais para "artefatos preliminares". Damos mais foco agora para conceitos de alto nível, casos de uso, histórias de usuário e diagramas de eventos. Os requisitos, entretanto, continuarão necessários devido aos contratos com o governo, mas são ruins como pontos de partida para o desenvolvimento;
- Refino do backlog e do planejamento das iterações, melhorando nossas estimativas. Estimar desenvolvimento de software é uma competência difícil de adquirir, mas extremamente importante em uma indústria em que os orçamentos e prazos são fixos;
- Inclusão da equipe de negócios mais próxima na iteração. Iterações frequentes fizeram com que os grupos de desenvolvimento e teste passassem a trabalhar coesos, mas ainda precisamos incluir a equipe de negócios.
Conclusões
Este artigo descreve um processo ágil simples adotado pelas minhas equipes de desenvolvimento na indústria de Defesa. Também traz uma visão de como migramos do modelo cascata para o ágil. Gerenciar equipes ágeis exige habilidade de fazer mudanças quando as coisas não estiverem indo bem. A principal característica de ser ágil é a vontade constante de implementar pequenas mudanças e fazer ajustes.