A era dos processos

Um processo de desenvolvimento de software é um conjunto de atividades, parcialmente ordenadas, com a finalidade de obter um produto de software. É um ramo da engenharia de software, e começou a ser estudado como uma resposta à “crise do software”.
Há várias décadas se tenta criar um processo previsível e repetível que melhore a produtividade e a qualidade no desenvolvimento de software. O mais antigo e bem conhecido processo é o modelo em cascata. Nele os desenvolvedores seguem os seguintes passos nessa ordem: estabelecem os requisitos, criam uma especificação, arquitetam a solução, implementam-na, realizam os testes, a implantam e a mantêm. Cada passo é iniciado apenas após o término do passo anterior.
De certa forma, esse processo pode ser comparado com uma linha de montagem, onde os requisitos fazem o papel de matéria-prima. À medida que uma fase do processo termina, existe um conjunto de artefatos gerados, normalmente sob a forma de documentos. Esses artefatos servem de ponto de partida para a fase posterior, onde são utilizados para gerar novos artefatos e passar adiante para a próxima fase. Sendo assim, os artefatos gerados servem para que a próxima etapa seja realizada de maneira cada vez mais mecânica e determinística, visando o cumprimento do planejamento, que por sua vez, foi realizado durante as etapas iniciais.
Grande parte dos artefatos é constituída de documentos que servem para guiar o trabalho a ser executado posteriormente. Esses documentos são redigidos por técnicos especializados pertencentes a equipe que desenvolve o software. Como na linha de montagem, cada técnico tem um papel específico dentro do projeto, então os artefatos produzidos por ele serão utilizados por outros membros de sua equipe. Por essa razão, esses documentos buscam capturar o máximo possível de informação a fim de que seja compreendido de maneira clara por outra pessoa.
Se esse objetivo for alcançado, o fluxo do trabalho se torna unidirecional, indo da etapa inicial para as posteriores, tal qual as águas correndo numa cascata. Daí o nome do processo, onde mais uma vez se usa uma metáfora.
Por ter sido o primeiro processo de desenvolvimento de software, o modelo em cascata segue muitas das idéias da Conferência da OTAN sobre Engenharia de Software. O fluxo unidirecional assemelha-se a metodologia de outras áreas da engenharia. Assim como na construção de edifícios, seus passos são seqüenciais: quando você constrói o décimo andar de um prédio, jamais voltará para revisar as fundações. Essa característica é uma conseqüência histórica, já que a OTAN visava a aplicação dessas idéias em grandes sistemas de defesa, e não nas áreas mais comuns da atualidade.
A Engenharia de Software surgiu com o objetivo de atender às necessidades da OTAN para o desenvolvimento de grandes sistemas de defesa. Em princípio, seu escopo não envolvia projetos de aplicações comerciais que, de um modo geral, são bem menores e precisam entrar em produção em pouco tempo. Nestes casos, são raros os projetos desenvolvidos por equipes de mais de 20 pessoas e a maioria dos desenvolvedores trabalha em equipes com menos de 10 membros.
Pete McBreen, Software craftsmanship: the new imperative
A principal deficiência do modelo em cascata está no fluxo unidirecional. Uma única característica do software, a ausência de conformidade, já é suficiente para arruinar um projeto sob esse processo. Uma pequena mudança de escopo num projeto que não pode rever as etapas passadas pode declarar o seu fim, dependendo de quão avançado seu desenvolvimento esteja. Acreditar que o modelo em cascata pode ser seguido à risca exige uma certa dose de fé, principalmente ao lembrar que o primeiro passo a ser realizado nele é o levantamento de requisitos.
Vamos explicar o porquê. O levantamento de requisitos é mais um trabalho de extração do que de análise em si. O usuário do software (o cliente) provavelmente acredita dominar todo o processo de sua atividade e conhecer todas as funcionalidades que deseja no software. Infelizmente no momento de repassar essa informação ao analista ou engenheiro ele não leva em consideração a incompletude, ambigüidade e contradição nos requerimentos. Em muitos casos o cliente jamais documentou o seu processo por escrito. Além disso, mesmo um analista experiente pode deixar escapar um detalhe nessa fase do desenvolvimento. Se a ausência desse detalhe for notada muito tarde, será impossível voltar atrás quando se segue o modelo em cascata.
O fluxo unidirecional também fere uma outra característica do software: a ilusão da maleabilidade. Uma vez que as mudanças de escopo tem um custo elevado no modelo em cascata, elas tendem a ser controladas e evitadas. Mas o cliente de um determinado projeto pode entrar em conflito com os desenvolvedores se esses simplesmente se negarem a adicionar uma nova funcionalidade que não havia sido prevista. Por fim, um fluxo unidirecional, no qual a implantação do sistema é um dos últimos passos, faz com que o cliente só tenha o contato com o software muito tarde, eliminando qualquer possibilidade de feedback.
Obviamente que essa desvantagem foi notada pelos engenheiros e uma evolução surgiu a partir daí. Essa solução consistia na utilização de um processo iterativo, construindo uma porção menor do software de cada vez para ajudar a descobrir problemas ou suposições falhas existentes. A iteração corresponde ao desenvolvimento de uma pequena parte do sistema, e segue o modelo seqüencial tradicional, da mesma forma que o modelo em cascata. Ao final de cada iteração o sistema é incrementado até que o ciclo de desenvolvimento termine.
O processo iterativo logo se tornou o favorito dos desenvolvedores comerciais, pois resolvia ao menos em parte o problema da ausência de conformidade. Mesmo que os requisitos mudassem no desenrolar do projeto, era possível uma adaptação na iteração seguinte. A engenharia de software parecia estar no caminho certo para encontrar o processo ideal.
A partir de então, um novo modelo viria a se destacar. O RUP (Rational Unified Process) é um processo de desenvolvimento de software iterativo e incremental, que utiliza a UML (Unified Modelind Language) na modelagem e especificação de seus artefatos. O RUP surgiu como uma reunião de “melhores práticas”. Dentre essas práticas, a equipe de desenvolvimento seleciona as mais adequadas para o projeto em questão. Para completar seu arcabouço o RUP também engloba um vasto número de artefatos.
No decorrer do tempo, o RUP foi adotado de diversas formas dentro das organizações. Um extremo foi usar o processo a risca, aplicando todos os métodos exatamente como propostos. A vantagem dessa abordagem vem do fato do RUP ser completo e detalhado. Porém existe um preço a se pagar: completude e detalhamento tornam o processo complexo. Em face disso grande parte das empresas trilhou um caminho diferente, adotando um processo mais simples e utilizando o material descrito no RUP como fonte de referência complementar.
Apesar da inegável contribuição do RUP para a engenharia de software, devemos notar que, na prática, ele não alcançou seus objetivos por ser mal utilizado.
Depois de quase 20 anos de obsessão por processos (…), o processo que encontro tipicamente em empresas clientes se tornou excessivamente baseado em documentações, gerando a enxurrada de documentos que se tornou endêmica (…).
Tom DeMarco e Barry Boehm. The agile methods fray
O mais notado mal-entendido com o uso do RUP tem sido a escolha das práticas e artefatos a serem utilizados. Pessoas com pouca experiência nesse processo tendem a adotar um conjunto desnecessário deles. Por temerem retirar elementos que possam ser úteis mais tarde, costumam levar o projeto a uma extrema burocratização, penalizando a equipe com a geração de documentos desnecessários.
É certo que a escolha de artefatos e práticas inúteis no contexto de um determinado projeto não se deve ao processo, mas é um caso de erro humano. Todavia, não podemos eximir o RUP de parte da culpa, pois ao oferecer uma infinidade de possibilidades ele gera confusão entre os desenvolvedores. O próprio conceito de melhores práticas é ambíguo, pois uma prática pode ser boa para um projeto e não para outro.
O RUP se utiliza fortemente da UML, sendo um processo orientado a casos de uso. Muitas equipes costumam utilizar esses casos de uso como a principal ferramenta para capturar os requisitos funcionais. Mas se nos lembrarmos de outra das características do software, a invisibilidade, notaremos que há um sério problema nisso. Os desenvolvedores que se utilizam do RUP freqüentemente consideram um caso de uso como um elemento suficiente para a implementação de funcionalidades. Dessa maneira, baseiam a implementação do software num documento escrito, que não consegue capturar certas nuances dos requisitos.
Por fim, o último ponto que recebe bastante críticas é o tamanho das iterações. Por geralmente usarem uma grande quantidade de artefatos, as equipes sob o processo RUP costumam reduzir o número de iterações, deixando cada uma delas mais longa. Não é raro executarem o projeto inteiro dentro de uma única iteração, no estilo do modelo em cascata. Essa prática elimina os benefícios do feedback do cliente, e incute em todos os problemas do modelo em cascata citados anteriormente.
Como vimos, a história da engenharia de software partiu de uma fase caótica no final dos anos 60, onde existia a total ausência de processos estabelecidos. Ao longo das décadas diversas soluções foram propostas, cada uma delas tentando corrigir os pontos fracos das anteriores. Então, chegamos no início dos anos 90 a processos extremamente completos e detalhados. Infelizmente, os desenvolvedores tornaram-se reféns de seus próprios medos, fadados a conviver com metodologias altamente burocráticas. Mas do emaranhado de práticas e documentos, viria a surgir a oportunidade para uma nova mudança.
Deixe seu comentário