Tradicionalmente, o desenvolvimento de software tem sido tratado e gerenciado como uma atividade de produção industrial. Este ponto de vista traz consigo uma série de conceitos e práticas como planejamento up-front detalhado, controle de escopo, controle de mudança, culminando em processos tayloristas e gerenciamento fordista. O resultado disto é um modelo de processo conhecido como cascata (ROYCE, 1970). Estas concepções partem de um ponto de vista que pensa o desenvolvimento de software como um processo de produção. O paradigma taylorista, desenvolvido pelo engenheiro Frederick Taylor(1995), visa à produção em série e em massa a baixos custos, utilizando para isto a racionalização organizacional da produção. Esta racionalização pressupõe basicamente a total separação entre o pensar e o fazer, dividindo processos de fabricação em um sem número de pequenas atividades, e a extrema especialização, para que estas pequenas atividades sejam realizadas de modo automático pelo trabalhador. Para levar a automatização humana às máximas conseqüências, foi criado um método no qual os trabalhadores se postavam ao lado de esteiras rolantes que traziam as peças a serem montadas e cada trabalhador tinha a especializadíssima tarefa de encaixar uma peça ou apertar uma porca. Aplicada na prática pelo industrial Henry Ford na fabricação de automóveis, a racionalização aplicada à esteira representou um brutal aumento de produtividade. Após Ford, outros industriais também descobriram que havia espaços livres para racionalização em suas fábricas e também aderiram à administração científica da produção, aplicada assim às indústrias de eletrodomésticos, entretenimentos eletrônicos, alimentos, utilidades domésticas e muitas outras. Assim, se as tarefas podem ser realizadas de modo automático, atinge-se total foco na execução das tarefas, sem pensamentos que atrapalhem ou desviem a produtividade das máquinas humanas de trabalho.
A abordagem tradicional para a engenharia de software, de modo análogo, busca a racionalização, fazendo com que suas atividades sejam o mais determinísticas possível, objetivando minorar erros e desperdício de tempo. Este paradigma leva também à noção de que deve existir uma rígida separação de funções e, conseqüentemente, de papéis, em uma equipe de desenvolvimento de software: profissionais de qualificação relativamente baixa para a fase de construção, os programadores, têm a responsabilidade única de executar fielmente o design feito pelos analistas, projetistas e arquitetos, os quais atuam nas fases anteriores de levantamento de requisitos e análise e projeto de software.
Um forte motivo pelo qual a indústria de software continua aferrada a estes paradigmas é a onipresença da famosa curva de custos de correção do software (BOEHM, 1981) por tempo transcorrido desde o início do processo, conforme mostra a Figura 1. Tomando esta curva como realista, a conseqüência lógica é tentar reunir no início do projeto o máximo possível de informações sobre o software, de modo que se minimize a necessidade de alterações em momentos tardios do processo de desenvolvimento. Assim, os métodos tradicionais preconizam fases iniciais abrangentes para o desenvolvimento de software. Nestas fases, as atividades primordiais são de planejamento do sistema: levantamento de requisitos, análise de sistemas, projeto, arquitetura. Quanto mais abrangente for o levantamento, maior chance de sucesso, pregam os modelos tradicionais, terá o software a ser implementado. Além do levantamento, a geração de documentação abrangente, com um grande número de artefatos, é prática padrão de métodos e certificações de processo associadas ao desenvolvimento tradicional como CMMI, MPS.BR e outros.
Na segunda metade da década de 1990 começaram a se estruturar linhas de pensamento em engenharia de software que preconizam que o desenvolvimento de software é realizado de modo mais adequado quando desempenhado em toda a sua extensão por trabalhadores do conhecimento, tendo muito maior semelhança com atividades de prestação de serviços do que manufaturas fordistas. O trabalho do conhecimento é fundamentalmente diferente, pois se caracteriza por: uma busca contínua por inovação em lugar de seguir estritamente um plano pré-estabelecido; disseminação do conhecimento por toda a hierarquia; conhecimento como insumo básico para a produção; e auto-gerenciamento. Estas características são exatamente aquelas que se deveria encontrar em equipes de desenvolvimento de software, e não linhas de montagem taylor-fordistas.
Softwares possuem características próprias que os tornam produtos especiais com algumas propriedades inerentes (BROOKS, 1995). A gigantesca quantidade de estados possíveis leva o software a ser um construto altamente complexo. Quando é necessário ampliar um software já existente, sua complexidade costuma ser incrementada mais que linearmente, devido ao aumento na quantidade de elementos envolvidos. Além disto, softwares são feitos para se adequar a ambientes sócio-econômicos, que sempre são complexos por si mesmos, além de sofrerem mudanças freqüentes. Assim, softwares precisam ser facilmente alteráveis. O fato de que o software é um construto invisível e dinâmico dificulta processos mentais e também a comunicação, uma vez que não há maneira de representá-lo gráfica ou espacialmente, a não ser que sejam usadas representações parciais como diagramas estruturais ou comportamentais. Tudo isto confirma que o software é inerentemente um produto do trabalho do conhecimento. Contudo, o desenvolvimento de software tem sido gerenciado com técnicas criadas para o gerenciamento de trabalho manual. O paradigma taylor-fordista, quando aplicado a esta área, torna-se uma triste analogia.
Desenvolvimento ágil, ou simplesmente agilismo, é um rótulo genérico para todos os métodos de desenvolvimento de software baseados no Manifesto Ágil (BECK et al., 2001). Este manifesto, assinado por alguns dos maiores nomes na comunidade de desenvolvimento de software, é apenas um breve documento preconizando quatro valores e doze princípios que apontam basicamente para: estreita colaboração e proximidade entre a equipe de desenvolvimento e os clientes; o reconhecimento de que mudanças nos requisitos representam aprendizado e oportunidades de obtenção de vantagens competitivas; busca por simplicidade e eliminação de documentações e processos desnecessários; ênfase nas pessoas em relação a processos; e o estabelecimento da geração de valor aos clientes como o objetivo por excelência e como a principal métrica de progresso. A maior parte destas idéias não é nova; contudo, a inovação dos proponentes do Manifesto Ágil reside em apresentá-las em um todo coeso.
Fowler (2005) lista as duas diferenças fundamentais entre as abordagens tradicional e ágil para desenvolvimento de software. Primeiro, abordagens ágeis são adaptativas ao invés de preditivas. Enquanto abordagens preditivas encaram a mudança como um problema a ser evitado e um caro e indesejado desvio do planejado, métodos adaptativos acolhem a mudança como uma oportunidade de melhoria. Em segundo lugar, abordagens ágeis são orientadas a pessoas, não a processos. Isto leva ao reconhecimento de que desenvolvedores de software são profissionais responsáveis e auto-gerenciados e não mais unidades de programação descartáveis e intercambiáveis. É importante notar que estas diferenças são as mesmas existentes entre o trabalho em manufaturas fabris e o trabalho do conhecimento.
Um dos principais problemas com as abordagens tradicionais é que elas procuram se precaver contra o futuro ao invés de estarem preparadas para ele. Como a premissa técnica básica é que o custo das alterações aumenta exponencialmente - ou quase isso - com o tempo, é preciso fazer planejamento e modelagem prévios em larga escala. Isto tem o efeito colateral de tornar o desenvolvimento de software uma aposta: todas as fichas são colocadas nos modelos e especificações de requisitos que são criados no início do projeto. Neste contexto, a mudança é uma inimiga, pois irá certamente ferir o planejamento, com consequências sobre alguma(s) das variáveis da gestão do projeto. Da visão negativa da mudança, surge a necessidade de controlá-la de modo férreo, o que acaba por gerar ainda mais efeitos negativos: as pessoas envolvidas no projeto, tanto a equipe de desenvolvimento quanto os clientes, são desestimulados a sugerir inovações.
Com efeito, Beck (2004) traz uma esclarecedora metáfora para explicar o problema deste tipo de visão. Imagine uma estrada infinitamente reta, sem curvas. Uma abordagem baseada em planejamento inicial abrangente e no cumprimento estrito do plano seria como passar horas verificando o volante e os pneus do carro para assegurar-se de que estão exatamente paralelos em relação à estrada, travar irremediavelmente o volante nesta direção e começar a viagem. Um mínimo erro de ângulo neste planejamento inicial e, passados alguns quilômetros, o carro estará fora da estrada. Ainda segundo a analogia, o correto seria como fazemos instintivamente: segurar o volante em um ângulo razoável, sem desperdiçar tempo buscando a perfeição, e ir acertando o volante regularmente. Se a estrada tiver curvas, então (o que irremediavelmente acontece no mundo real, inclusive continuando a analogia com projetos de desenvolvimento de software), esta abordagem se adapta suavemente a mudanças, em lugar de lutar contra elas.
Sob um ponto de vista ágil, a mudança, mais do que reconhecida, é bem vinda. De fato, Cohn (2006, p. 6, tradução nossa) afirma que se tivesse que definir um projeto como fracassado, um de seus critérios seria "um projeto no qual ninguém veio com ideias melhores do que aquelas que estavam na lista inicial de requisitos". Do mesmo modo, assim define um plano ágil:
Um plano ágil é aquele que nós não só iremos, como estamos ansiosos para mudar. Nós não queremos mudar o plano apenas pela mudança, nós queremos mudar porque a mudança significa que nós aprendemos algo ou evitamos um erro (COHN, 2006, p. 9, tradução nossa)
Assim, diferentemente das abordagens tradicionais, os métodos ágeis não fazem um planejamento up-front abrangente (que aqui chamaremos BPUF, do inglês Big Planning Up Front). Sob um ponto de vista ágil, "o planejamento é um constante processo de reavaliação e correção de curso durante todo o ciclo de vida do projeto" (BECK; FOWLER, 2000, tradução nossa). Desenvolvimento significa um processo de aprendizagem, um exercício de descoberta (POPPENDIECK; POPPENDIECK, 2003). E um planejamento constante constitui, justamente, o ponto chave para se atingir um processo que acomode o aprendizado. Contudo, é impossível se produzir conhecimento, e por conseqüência, aprendizado, durante um projeto se a equipe de desenvolvimento tem pouco ou nenhum contato com os clientes, que são os produtores últimos das especificações que o software precisa cumprir. De fato, os métodos ágeis preconizam que os desenvolvedores e os clientes construam um relacionamento de cooperação estreita, para que as atividades de desenvolvimento sejam baseadas em feedback concreto e não em especulações sobre o futuro, o que é comum nas abordagens tradicionais.
Outro efeito do BPUF é o inchaço do software com funcionalidades que são pouco ou nunca utilizadas. Em estudo citado por Teles (2005) e Bain (2008), tem-se que 45% das funcionalidades implementadas em um software típico nunca são utilizadas, 19% raramente são utilizadas, 16% algumas vezes, 13% frequentemente e apenas 7% sempre. Ou seja, 45% do trabalho realizado em desenvolvimento de software é um desperdício inútil e apenas 20% são a parte que mais gera retorno para o cliente. Isto ocorre porque quando o cliente sabe que tem um momento onde precisará definir tudo que o software terá dali a um bom tempo, sem ainda ter visto nenhum software, ele fatalmente irá incluir tudo o que acha que será preciso. Brooks (1995) afirmou ser impossível para os clientes especificar, de um modo completo e preciso, os requisitos exatos de um projeto de software relativamente complexo antes de efetivamente utilizar algumas versões deste software. Isto significa que software em funcionamento é uma valiosa ferramenta de levantamento de requisitos, o que vai frontalmente contra o ciclo de vida baseado em fases das abordagens tradicionais baseadas em cascata, nas quais a programação (a atividade que gera software) somente é realizada em um momento tardio no projeto, quando os requisitos supostamente já estão levantados e estabilizados. Para obter um aprendizado efetivo durante o projeto, o software entregue aos usuários para auxiliar o levantamento de requisitos deve ter qualidade de produção e ser uma versão plenamente funcional, e não apenas um protótipo. Tudo isto leva à conclusão de que software funcionando é uma excelente (talvez a melhor) ferramenta para levantamento de requisitos.
A requisição de funcionalidades que não serão úteis traz ainda mais riscos para o projeto. Em um esquema de escopo fechado e definido no início do projeto, não há a necessidade de que a equipe de desenvolvimento priorize a implementação de nenhuma funcionalidade em especial, uma vez que, por contrato, todas as funcionalidades deverão ser implementadas. Quando há qualquer problema, há uma razoável probabilidade, dependendo de quando ocorre o problema, de que as mais importantes funcionalidades do software, do ponto de vista do cliente, ainda não estejam implementadas. Se o projeto, por qualquer motivo, é terminado neste ponto, o cliente terá um conjunto virtualmente desconexo de funcionalidades, com boa probabilidade de que o software gerado até então não seja capaz de resolver as principais questões de seu negócio.
Os métodos ágeis atacam esta questão com o uso de iterações curtas. Em curtos períodos de tempo, software funcional é liberado para que os clientes possam verificar se o software implementado é exatamente aquele de que necessitam e que lhes gerará valor. Para cada iteração é alocado um pequeno número de funcionalidades, que serão implementadas pela equipe de desenvolvimento durante a iteração. As iterações devem ser tão curtas quanto possível, o que significa que o software é liberado em incrementos pequenos e freqüentes. Deste modo, é possível tanto para os desenvolvedores quanto para os usuários explorar incrementalmente os requisitos e a maneira como o software vai sendo construído, permitindo uma melhor conformidade com as demandas do negócio. Além disto, quanto menores os incrementos e quanto mais curta é a iteração, mais rápido é o ciclo de feedback, levando a um controle de granularidade extremamente fina sobre o projeto e permitindo rápida correção quando o software começa a divergir das necessidades do negócio (MARTIN, 1999).
Do mesmo modo, o processo de levantamento de requisitos também é incremental. As funcionalidades não são detalhadas no início do projeto, apenas uma lista de funcionalidades é extraída inicialmente. Neste contexto, cada item desta lista não é um requisito, mas apenas um registro de sua existência, um compromisso de detalhamento futuro, um convite ao diálogo (JEFFRIES; ANDERSON; HENDRICKSON, 2001). Os detalhes acerca de uma funcionalidade são apenas analisados em profundidade na iteração na qual a funcionalidade é alocada.
No decorrer de um projeto, a lista de funcionalidades pode ser alterada diversas vezes pelos clientes, refletindo seu aprendizado sobre o software sendo criado e sobre suas próprias necessidades. A lista de funcionalidades, por sua vez, é priorizada em termos de valor de negócio: as funcionalidades consideradas mais importantes são implementadas primeiro. Isto constitui uma poderosa ferramenta para minimizar desperdícios e promover a simplicidade no desenvolvimento de software, uma vez que a decisão sobre o que será o escopo global do software não é tomada de uma só vez no início do projeto, mas iterativamente em seu decorrer. Assim, apenas as funcionalidades realmente necessárias são implementadas.
Para dar suporte ao caráter fortemente iterativo e incremental proposto, as abordagens ágeis exigem o uso de técnicas que assegurem que o software não irá cair em uma espiral entrópica de caos e desordem antes mesmo do término do projeto. Estas técnicas utilizam especificações que são compreensíveis e validáveis pelo cliente, mas, ao mesmo tempo, executáveis. Ou seja, o mesmo processo utilizado para levantamento de requisitos é utilizado para a verificação e a validação do software. É a técnica conhecida como Behaviour-Driven Development, que, além destas áreas, tem forte atuação também no design de software, constituindo, seja como BDD ou sob a forma de sua inspiradora, o Test-Driven Development, e juntamente com a integração contínua, a espinha-dorsal que viabiliza a aplicação das abordagens ágeis.
Estas técnicas de especificação automatizada são aplicadas a cada iteração, e eliminam as fronteiras entre análise, projeto e codificação. Assim, a divisão entre analistas, programadores, projetistas e outras, que gera problemas de comunicação e a criação de subequipes, cada qual preocupada apenas com seu próprio subdomínio, é rompida pelos projetos ágeis, restando um profissional único, o desenvolvedor de software.
Outro ponto importante para os métodos ágeis é a busca por melhoria contínua: em intervalos regulares, equipes ágeis devem refletir acerca de suas práticas e pensar modos de ser mais eficiente, ajustando seu comportamento para esta meta (BECK et al., 2001; DERBY; LARSEN, 2006).
Tudo isto apenas é possível porque se constatou que a curva de Boehm, mostrada na Figura 1, não é mais válida, devido a diversos avanços do desenvolvimento de software nas últimas décadas, citados por Teles (2004):
- melhores linguagens de programação;
- avanços na tecnologia da banco de dados
- melhores práticas de programação (MARTIN, 2008; BECK, 2007; MCCONNELL, 2004);
- novos ambientes e ferramentas de desenvolvimento;
- computadores mil vezes mais rápidos e mil vezes mais baratos (1 milhão de vezes mais poder de processamento por unidade monetária);
Referências
BAIN, S. Emergent Design: The Evolutionary Nature of Professional Software Development. New York: Addison-Wesley, 2008.
BECK, K. et al. Manifesto for Agile Software Development. 2001. Disponível em: <http://agilemanifesto.org>. Acesso em: 26/06/2010.
BECK, K. Programação Extrema Explicada: Acolha as Mudancas. Porto Alegre: Bookman, 2004.
BECK, K. Implementation Patterns. New York: Addison-Wesley, 2007.
BECK, K.; FOWLER, M. Planning Extreme Programming. New York: Addison-Wesley, 2000.
BOEHM, B. Software Engineering Economics. New York: Prentice-Hall, 1981.
BROOKS, F. The Mythical Man-Month. New York: Addison-Wesley, 1995.
COHN, M. Agile Estimating and Planning. Upper Saddle River/NJ/EUA: Pearson Education, 2006.
DERBY, E.; LARSEN, D. Agile Retrospectives: Making Good Teams Great. Dallas: The Pragmatic Bookshelf, 2006.
FOWLER, M. The New Methodology. 2005. Disponí́vel em: <http://martinfowler.com/articles/newMethodology.html>. Acesso em: 26/06/2010.
JEFFRIES, R.; ANDERSON, A.; HENDRICKSON, C. Extreme Programming Installed. New York: Addison-Wesley, 2001.
MARTIN, R. Iterative and Incremental Development. 1999. Disponível em: <http://www.objectmentor.com/resources/articles/IIDII.pdf>. Acesso em: 26/06/2010.
MARTIN, R. Clean Code: A Handbook of Agile Software Craftsmanship. New York: Prentice-Hall, 2008.
MCCONNELL, S. Code Complete: A Pratical Handbook of Software Construction. 2. ed. New York: Microsoft Press, 2004.
POPPENDIECK, M.; POPPENDIECK, T. Lean Software Development: An Agile Toolkit. New York: Addison-Wesley, 2003.
ROYCE, W. "Managing the Development of Large Software Systems". IEEE WESCON, IEEE, v. 26, p. 1–9, 1970.
TAYLOR, F. Princípios da Administração Científica. 8. ed. São Paulo: Atlas, 1990.
TELES, V. Um Estudo de Caso da Adocao das Práticas e Valores do Extreme Programming. Dissertação (Mestrado em Informática) — Núcleo de Computação Eletrônica/Universidade Federal do Rio de Janeiro, Rio de Janeiro, 2005.
TELES, V. Extreme Programming: Aprenda Como Encantar Seus Usuários Desenvolvendo Software com Agilidade e Alta Qualidade. São Paulo: Novatec, 2004.

Powered by: