Durante um único dia de trabalho de uma equipe ágil temos alguns instantes que fazemos a reunião em pé do XP ou o encontro diário do Scrum. Esta mini-reunião é um ponto de sincronização do status do projeto (é uma inspeção no ciclo da iteração). O Scrum sugere que essa reunião tome o tempo máximo de 15 minutos. Dentro de um dia de trabalho de uma equipe ágil, fora desses poucos minutos preocupados com o gerenciamento a equipe trabalha no sentido de fazer incrementos de software funcionar de maneira “atômica”, isto é, um pequeno requisito é capturado e rapidamente transformado em software funcionando. Isso é o ciclo ágil de um dia. Assunto que tratarei na próxima edição da MundoJava.
Uma caracterísca marcante do ciclo ágil de um dia é que ele é não precisa ser gerenciado no nível macro, isto é, ele não pode ser tomado como base para o andamento do projeto como um todo. Somente com software funcionando e usuários felizes é que você pode dizer que o projeto andou. Este ciclo ocorre de maneira muito rápida e quem gerencia é o próprio desenvolvedor. Essa responsabilidade é uma cultura auto-organizável que faz parte do cerne do gerenciamento ágil. Gerentes de Projeto e Coordenadores não devem interferir no trabalho que é responsabilidade técnica dos desenvolvedores.
Os pontos que defendo aqui são práticas ágeis essencialmente constantes na metodologia XP e no TDD. Infelizmente essas práticas não são adotadas na maioria das equipes que tive contato. Um padrão muito comum nas equipes são práticas fantasiadas de Unified Process (ou RUP) que seguem um formato “Casos de Uso - UML - Codificação - Teste”, seguindo basicamente um processo em cascata numa escala menor. Este modelo dá a entender que requisitos estão em Casos de Uso (geralmente em documentos Word), o projeto ou arquitetura está no modelo UML (uma abstração intermediária), o código simplemente é algo que o computador compreende e, ao final, testes baseados no Caso de Uso são aplicados.
Primeiramente, gostaria de deixar claro que esta pode ser uma maneira de você implementar uma funcionalidade específica de um usuário com certo sucesso, porém, esse tipo de desenvolvimento não deve ser sequêncial e nem mesmo ser um padrão para todas as funcionalidades e nem para todos os projetos. Se a funcionalidade é simples e a expectativa do usuário está clara, documentos de Casos de Uso e modelos UML podem ser descartados. Porém, existem outras maneiras de você alcançar este mesmo objetivo! O próprio RUP não prega este tipo de prática.
Este anti-pattern causa uma cegueira técnica. O fato de sempre ter Casos de Uso, UML, Código e Testes em cascata leva a equipe a acreditar que todos os requisitos estão em casos de uso, temos que modelar tudo e codificar é uma atividade pouco criativa, assim como os testes. Porém, se verificarmos que estatisticamente somente um terço dos requisitos estão em casos de uso [Cockburn], que modelamos somente o que precisa ser modelado [Yoshima] e que todo o processo de desenvolvimento de software é uma atividade criativa (inclusive os testes [Fowler]), vemos que este padrão é muito questionável e muito dispendioso.
Você pode utilizar Casos de Uso para capturar requisitos e utilizar UML para analisar um problema. A culpa não é dessas ferramentas! O maior problema desse padrão é não conversar mais com os usuários depois que o Caso de Uso está escrito, roubando sorrateiramente a comunicação entre a equipe técnica e o cliente durante o desenvolvimento. Refinamentos surgem o tempo todo! A equipe precisa durante o desenvolvimento ligar para o cliente e tirar dúvidas! É comum que durante a codificação novos requisitos não capturados emergam. Requisitos capturados, modelados, codificados e testados podem não ser o que o usuário queria de fato, pois artefatos como Casos de Uso e modelos UML são propensos a muitas imperfeições (são abstrações e não são naturalmente executáveis).
Vejo que o padrão “Caso de Uso - UML - Codificação - Teste” é uma má influência do processo Waterfall, que declaradamente é uma péssima prática para desenvolvimento de software. Esse pensamento seqüencial é ainda mais danoso quando tentamos encaixar este padrão dentro da divisão e especialização de trabalho do Taylorismo, comum em fábricas de software. Nesse cenário, um analista de negócios escreve Casos de Uso, um analista de sistemas desenha o modelo, um programador codifica e um testador testa. Essa equipe muitas vezes utiliza artefatos para se comunicar (e logicamente, cada passo geralmente é controlado por um Gantt Chart). Antes de prosseguir, veja a citação de Kent Beck a respeito do Taylorismo:
“Especialização e rigorosamente dividir e conquistar serviu para produzir mais carros de maneira mais barata. Na minha experiência esses princípios não fazem sentido como estratégia para desenvolvimento de software. Nem para o negócio e nem para o lado humano eles fazem sentido.” Kent Beck
A base da divisão do trabalho é que é possível quebrar um determinado processo em partes menores gerenciáveis, e se cada parte for otimizada, o processo como um todo é otimizado. A especialização diz que determinado recurso efetuando uma tarefa várias vezes torna-se ótimo para esta tarefa. A questão é que para desenvolvimento de software, nem sempre a soma “Casos de Uso + UML + Código + Testes” geram algo do agrado do usuário se ele não estiver envolvido em todo o ciclo. Isso nos mostra que esses passos não são mensuráveis. Além disso, um analista de negócio não se tornará um analista de negócio melhor se ele escrever muitos Casos de Uso, assim como acontece com um Analista de Sistemas ou Programador.
Desenvolvimento de software não é um processo mecânico. Todas as metodologias atuais pregam um trabalho coletivo, em constante comunicação, entrosamento e principalmente uma visão holística sobre o projeto (o todo, e não as partes). Se apegar a rígidos papéis e responsabilidades é péssimo sob qualquer aspecto para uma equipe que desenvolve software.