Archive for the 'agile' Category

Seja bem-vinda, manutenção!

É bastante comum ver organizações que costumam desenvolver software em cascata espernear quando chega a hora de implantar e colocar os sistemas em produção. Depois que tudo está instalado e funcionando a todo vapor elas acabam entrando em modo bombeiro e passam simplesmente a apagar um incêndio atrás do outro, sem saber muito o que fazer e como organizar seus esforços de manutenção.

Isto costuma acontecer porque a abordagem de desenvolvimento delas simplesmente não está adaptada à manutenção. Ela foi otimizada para um cenário (completamente fictício, diga-se de passagem) onde não há vida após a entrega do sistema, onde os clientes não mudam de idéia e onde não acontecem requisições de mudança depois que o software está pronto.

Não importa quanto alguém se dedique à tarefa. Ninguém consegue fazer a água da cascata cair para cima.

A abordagem oposta, obviamente, é otimizar para a manutenção, isto é, estar pronto para começar pequeno, mudar sempre que necessário, consertar o software aos poucos e torcer para que um dia ele não precise mais de conserto. A proposta Ágil começou com experiências neste sentido, tomando emprestado da filosofia release early, release often e preferindo usar o próprio software para comunicação entre os clientes e a equipe de desenvolvimento ao invés de documentos e diagramas. Num certo sentido, equipes ágeis tomam a manutenção como modo de operação normal no lugar do desenvolvimento puro. Preferem desenvolver uma solução completa e usável para um problema pequeno rapidamente para que possam dar as boas vindas à manutenção o mais cedo possível. Enquanto os clientes não tem uma peça real de sofware para usar e experimentar, suas sugestões são só um pouco melhor do que especulação.

Esta não é uma idéia tão louca no fim das contas. Pensando bem, da segunda linha de código para a frente tudo é manutenção.

Anúncios

A evidência definitiva da programação saudável

Como alguém pode saber que uma equipe de programadores desenvolve software com um processo saudável? Como podemos saber se as práticas adotadas pela equipe são suficientes para produzir software útil, correto e de fácil manutenção? Quais as evidências que devemos procurar para separar os bons projetos dos ruins?

Estas são questões fundamentais tanto para quem está procurando um fornecedor como para quem está projetando um novo selo ou certificado parecido com os milhares que já temos para identificar organizações que sabem desenvolver software. Quem se propõe a fornecer um selo desse tipo precisa observar o trabalho dos candidatos por algum tempo para tentar encontrar algumas evidências de um processo saudável e sustentável. Precisa procurar pelos rastros deixados por um trabalho bem feito.

Uma forma razoável de identificar estes rastros é projetar um processo de desenvolvimento que comprovadamente dá certo (pelo menos para alguns casos) e verificar o que uma equipe que usou este processo deixou pelo caminho. Alguns selos em uso atualmente fazem exatamente isso: eles certificam toda uma classe de processos que produzem os mesmos subprodutos que um processo original. As equipes que querem ser certificadas precisam aprender o modo de operação e repetí-lo, produzindo evidências concretas de que seguiram um processo aprovado pelo certificador. Documentos de requisitos, relações de casos de uso, matrizes de rastreabilidade, diagramas de relacionamento e relatórios de revisão são todos exemplos de evidências bastante tangíveis da existência de procedimentos definidos.

Porém nenhum desses documentos pode ser considerado uma evidência definitiva da qualidade do processo. Nenhum deles consegue provar sozinho que o processo de desenvolvimento funciona.

Nem mesmo todos eles juntos conseguem fazer isso.

A evidência definitiva de um processo de desenvolvimento de software saudável é bastante óbvia, mas isso não quer dizer que todo mundo consegue enxergá-la. O único produto suficiente e necessário para identificar que um processo realmente dá certo é simplesmente software funcionando.

Só isso.

Não são documentos de requisitos bem escritos, matrizes de rastreabilidade gigantescas, nem diagramas bonitos e coloridos. A maior evidência que se pode observar em projetos saudáveis é a simples entrega de software funcionando. Deve ser suficiente observar que uma equipe consegue entregar software funcionando a cada, digamos, uma ou duas semanas para saber que eles têm uma boa abordagem para desenvolvimento de software. Uma queda da velocidade de evolução do sistema é o que basta para saber que algo vai errado.

Nem todos os processos de desenvolvimento são projetados para entregar software funcionando dentro de períodos curtos de tempo. Por isso desenvolveram-se vários modelos que verificam subprodutos intermediários como diagramas de estado e especificações funcionais. É um caso clássico de quem não tem cão, caça com gato. Estes subprodutos servem como promessas, garantias, evidências de que em algum momento futuro o sistema será entregue como esperado. O problema é que nenhum subproduto desses é tão verificável quanto o produto final. Eles servem para tranqüilizar um pouco os clientes, que de um modo ou de outro recebem algumas garantias de que seu dinheiro está sendo bem gasto. Mas definitivamente não servem para dar certeza do sucesso do projeto, nem ao menos da transformação do produto em software funcionando.

Fábricas de software – Uma analogia levada longe demais

Analogias costumam ser usadas para tentar entender melhor algo. A idéia é bastante simples: compara-se o objeto ou conceito que não se conhece a outro bem conhecido com o objetivo de aprender alguma coisa ou formar algum argumento. Muito já se descobriu com ajuda das analogias, mas elas também podem ser bem perigosas. Eu poderia repetir tudo aqui, mas o Marcos Pereira saiu na minha frente com o primeiro artigo do seu novo blog que discute várias das mais furadas analogias para desenvolvimento de software (e uma das certeiras). Ao invés disso, este artigo vai se deter em apenas uma delas: a das fábricas.

Fábricas são instalações onde as pessoas se reúnem para produzir um certo tipo de artigo. Fábricas de sapatos fazem sapatos, fábricas de postes fazem postes e fábricas de software fazem software.

Simples assim.

Mas nem tanto…

Fábricas são instalações com estrutura e procedimentos de produção pautados por um certo modelo. Afinal de contas, não são só as fábricas que se encaixam na definição acima. Organizações como oficinas e ateliês também podem perfeitamente produzir artigos de qualidade. A diferença está na organização interna.

Um dos maiores problemas das analogias é que costumam ter limites não muito bem definidos. Toda analogia tem um ponto de quebra a partir do qual não faz mais sentido e nem sempre é fácil identificar até onde podem ser aplicadas. Nas mais rasas este ponto de quebra é alcançado bem rapidamente como neste caso das fábricas.

Ao pensar em fábricas é comum lembrar de linhas de montagem, funcionários altamente especializados e produção em massa. Tudo isso faz muito sentido em boa parte das fábricas, como as de sapatos, automóveis e componentes eletrônicos, mas não tem grande valor para quem produz software.

Software não se encaixa num modelo de produção em massa e manufatura porque não é repetição. Fazer software é projetar, não construir. Ninguém pensa em fazer o mesmo projeto do mesmo sistema duas vezes, mas muita gente pensa em licenciar para dois clientes diferentes. Fábricas são excelentes para reproduzir produtos idênticos ou com pouca variação, mas projetar software — assim como projetar carros, telefones e praticamente qualquer coisa que se possa imaginar — é um processo criativo que não se adapta muito bem à manufatura. Fábricas são bastante eficientes para reproduzir produtos em larga escala. Só que ninguém precisa de uma fábrica para reproduzir software, uma máquina de prensar discos já basta (sim, desenvolvedores web, ainda existe gente que precisa distribuir software em discos).

Muitos programadores felizmente já notaram que especialização extrema e processos de desenvolvimento repletos de fases — e, conseqüentemente, entregas parciais — não fazem muito sentido. Estas abordagens servem muito bem para reproduzir produtos. Só que software não é feito de madeira e cola, nem de aço e solda. Mas de idéias e bytes. Por causa de sua natureza imaterial, reproduzir software é muito simples e barato. Portanto, o problema da reprodução já está resolvido, o que queremos é projetar software com qualidade e de forma economicamente eficaz. Este é o fator primordial que impede esta analogia de ir tão longe.

Muita gente sabe disso, mas misteriosamente ainda gosta de chamar suas organizações de fábricas. Ao contrário do que possa parecer, alguns desses não são completos idiotas e sabem pelo menos alguma coisa do que estão falando. Quando falam em fábricas, eles não estão pensando em programadores operários apertando parafusos, mas em coisas interessantes como linguagens para certos domínios de conhecimento e frameworks especializados. Apesar disso, essas pessoas fazem esforços tremendos para extrapolar a metáfora e chegam a chamar linguagens de fábricas (é verdade, essa eu vi em uma lista de discussão que, infelizmente, não tem arquivos públicos e não pode ser referenciada aqui). Várias dessas idéias fazem todo o sentido do mundo, mas definitivamente não são fábricas.

Provavelmente muitos dos pesquisadores modernos fazem a analogia por razões históricas e não de forma intencional. O problema é que, devido a sua natureza metafórica, a expressão pode ser mal interpretada e, infelizmente, isso não acontece tão raramente quanto gostaríamos. Tem gente que gosta de fingir que acompanha as novidades do meio acadêmico e já viu a expressão “fábrica de software” repetida várias vezes em títulos de artigos científicos. Mas o título deve ser a única linha que eles lêem. Depois de olhar para o nome, acham que podem organizar suas “fábricas” exatamente como manufaturas juntando programadores aos montes para repetir código e fazer trabalho mecânico em geral. Afinal, parece ser a última moda entres esses cientistas inteligentes e deu certo para as fábricas de sapato na China, não deu?

O resultado são fábricas de software funcionando (ou tentando funcionar) igualzinho a fábricas de sapato. Os programadores que dão o azar de ser tratados como máquinas de costura esperneiam de um lado dizendo que esta é a pior idéia desde a bola quadrada e os pesquisadores esperneiam do outro dizendo que o conceito deles de fábrica na verdade é uma boa idéia que não tem nada a ver com aquilo. Enquanto isso os leitores de títulos continuam a construir mais fábricas segundo seu próprio conceito para perpetuar a confusão.

Boa parte disso tudo simplesmente por causa de uma analogia que foi levada longe demais.

Assinar acordos não é entrar em acordo

Toda equipe que desenvolve software já deve ter descoberto que “o entendimento dos requisitos deve ser alcançado.” Eles podem ter lido isso em algum lugar ou simplesmente enxergado algo que é óbvio demais para ser ignorado por qualquer mente saudável. Não importa como chegaram a tomar conhecimento disso, o importante é que qualquer pessoa que se propõe a resolver o problema de outra sabe que precisa entender razoavelmente bem o que está querendo solucionar. A questão interessante é desenvolver uma maneira eficiente de fazer isso.

Uma alternativa que faz muito sentido é tentar escrever e assinar junto com os clientes um belo documento que descreva detalhadamente os requisitos. Esta estratégia parece bastante natural porque a maioria das pessoas já está bem familiarizada com assinaturas e contratos. Afinal não é exagero dizer que este tipo de formalização vem sendo usado há séculos nos mais variados campos de atividade.

Acordo ilusórioPor causa disso não é muito intuitivo pensar que esta abordagem tem um alto potencial para falta de entendimento. Como as coisas estão somente descritas e não há algo realmente tangível para guiar as opiniões, o entendimento depende totalmente da interpretação do texto e é possível que cada uma das partes tenha uma idéia diferente do objeto do acordo na hora da assinatura. Para que um acordo verdadeiro seja firmado, é essencial que ambas as partes estejam pensando na mesma coisa. Sem isso o máximo que se consegue é uma ilusão. Por causa do papel crucial da interpretação do texto, é comum que este tipo de engano ocorra ao usar apenas documentos. Apesar disso as assinaturas geralmente são aceitas como evidências de acordo.

Documentos fazem muito sentido quando o desenvolvimento do produto final precisa levar muito tempo. Quando isto é verdade o registro por escrito dos requisitos é uma opção aceitável. Há o risco de um acordo ilusório, mas ele é menos prejudicial para ambas as partes do que o cancelamento da empreitada. Porém quando os requisitos podem ser suficientemente pequenos e a equipe tem um processo de desenvolvimento suficientemente enxuto, as necessidades do cliente podem ser identificadas na segunda-feira e estarem materializadas em software rodando na sexta-feira seguinte (se é que software pode ser materializado). Quando isto é possível não faz mais sentido utilizar documentos e correr o risco de um falso acordo porque o produto final pode ser usado como objeto do acordo.

Software em execução é a forma mais incontestável de entendimento dos requisitos. Ninguém pode dizer que a equipe de desenvolvimento e o cliente não estão de acordo quando eles concordam sobre o produto final. Não há mais o que refinar, portanto não há mais onde discordar.

É “guiado”, oras!

Provavelmente vou mexer em um vespeiro dos grandes com o texto de hoje. Pelo menos é o que eu vejo acontecer quando alguém resolve desafiar, questionar ou simplesmente comentar qualquer coisa no campo da Agilidade (com letra maiúscula mesmo). Neste pequeno mundo, você nunca sabe quando está mexendo com alguma coisa sagrada para alguma pessoa. Também é o que eu vejo acontecer quando programadores discutem a questão traduzir ou não traduzir. Então parece que são dois vespeiros ao invés de um só. Mas eu gosto de exercitar a iconoclastia sempre que possível e vou continuar com o texto apesar de tudo.

Não sei como surgiu a tradução que parece ser normalmente usada por todo mundo aqui pelas bandas do Brasil para “Test Driven Development”, mas eu simplesmente não consigo evitar um certo incômodo mental quando alguém cita “Desenvolvimento Orientado a Testes”.

Pronto falei. Podem jogar as pedras.

Não é que os símbolos tenham algum papel extremamente relevante quando usados por pessoas com o mesmo domínio sobre o vocabulário. Evidentemente, não há nenhum problema nas palavras em si quando as pessoas sabem do que se está falando. Mas é quem não sabe que me preocupa.

Esta expressão “orientado a” deve ter vindo do mesmo baú do qual foram tirados alguns outros termos da moda como Programação Orientada a Objetos e Arquitetura Orientada a Serviços (que, como todo bom modismo, também costumam ser completamente mal interpretados). Não vou recorrer ao lugar comum de consultar um dicionário, mas este termo pode levar muita gente a pensar em simplesmente atentar para os testes e projetar sistemas testáveis. Esta postura certamente é melhor que não dar atenção nenhuma aos testes e relegar a atividade ao décimo-oitavo plano para ser realizada um pouco antes da implantação no caso de sobrar algum tempo. “Desenvolvimento Orientado por Testes” é um pouco menos ambíguo. Mas prefiro “Desenvolvimento Guiado por Testes” tanto por ser mais fiel ao original quanto por eliminar o já sobrecarregado termo “orientado”.

Desenvolvimento guiado por testes envolve uma certa atenção aos testes, mas também uma porção de outras escolhas técnicas e filosóficas. Envolve obrigatoriamente escrever os testes antes do código. Afinal, você não pode ser guiado por algo que não existe. Quando se abraça esta filosofia, os testes acabam virando uma das principais razões da existência do código, logo abaixo das necessidades do usuário. Certamente estas últimas são muito mais importantes do que os primeiros, mas um conjunto de testes bem projetado será o melhor reflexo das necessidades do usuário.

Mas, como disse, sou um iconoclasta atento e não acho que este tipo de posicionamento mental seja ideal para todos os casos. Particularmente, quando estou investigando algum tipo de tecnologia que imagino que vou precisar e com a qual ainda não tenho muita familiaridade, prefiro desenvolver apenas orientado a testes. Mantenho sempre a mente atenta à testabilidade, mas não necessariamente chego a escrever os testes. Depois que consigo algum domínio sobre a tecnologia, costumo voltar ao desenvolvimento guiado por testes e faço tudo que posso para escrever os testes antes do código de produção.

De qualquer modo, os termos em si não são tão importantes. São apenas símbolos e, se usados no contexto correto, não costumam gerar nenhum tipo de confusão. O importante são as diferenças filosóficas denotadas por eles.

Acho que minha doidice por linguagens de programação está começando a gerar uma doidice por linguagens naturais. Vai saber…

Pequenas vitórias

Todos nós já experimentamos. Alguns se arrependem e outros nem tanto. Alguns conseguiram encontrar um modo de se livrar e outros nem tentaram. Mas quase todo programador já trabalhou em “modo cego”.

Por meses seguidos.

Saber quando uma equipe está trabalhando em modo cego é fácil: é só perguntar quanto tempo faz desde que receberam algum tipo de comentário de um usuário final. Mais de um mês é um bom sinal de que estão ficando cegos. O tempo exato depende muito do tipo de aplicação que estão desenvolvendo, mas um mês geralmente é tempo demais para andar sem saber para onde vai. Além disso, não faz mal lembrar que um representante do usuário é melhor do que nada, mas não é páreo para um usuário de verdade.

Evitar entrar em modo cego também é fácil: basta estipular um prazo curto e entregar a aplicação do modo como estiver quando a data chegar. Durante este período a equipe exercita simultaneamente todas as habilidades que os aspirantes a desenvolvedor de software tão sabiamente estudam nas suas escolas, de modo a ter sempre algo usável. Fazer isso dá trabalho porque é preciso tomar algumas providências para garantir que a aplicação esteja pronta para ser entregue a todo momento. Afinal, a equipe certamente não vai querer chegar à data combinada sem ter algo apresentável. Mas não é nada humanamente impossível.

Apesar da atenção precisar ser redobrada, o resultado compensa. O usuário poderá oferecer seus comentários depois de ter colocado as mãos em algo concreto. Qualquer forma de tentar artificializar esta experiência através de documentos de especificação, apresentações elaboradas ou emaranhados de diagramas com certeza não oferecerá a mesma expressividade.

A possibilidade de receber continuamente comentários e sugestões de qualidade funciona como poderoso combustível para o potencial da equipe. Quando esta força energizante está disponível, há mais chance de se obter o sucesso. Há mais chance para vencer. Porém, como os períodos de iteração são curtos, estas vitórias serão necessariamente pequenas. Não há tempo para fazer nada muito grandioso e será necessário saber acumular estas pequenas vitórias ao longo do tempo para atingir uma vitória maior.

Ciclos curtos permitem que sejam alcançadas pequenas vitórias. Fracassos vão inevitavelmente se interpor no caminho da equipe, mas também serão pequenos. Estarão contidos em um período suficientemente pequeno para que não causem grande estrago e as vitórias serão tão mais freqüentes que eles passarão quase desapercebidos. Uma vitória pequena puxa a outra, e uma derrota pequena não faz muita diferença. Assim o moral da equipe é estimulado e o sucesso é naturalmente atraído. Ciclos longos, por outro lado, permitem causar grandes surpresas. Quando se trabalha muito tempo sem divulgar sua evolução, o resultado só pode ser grandioso. Se for um sucesso, será uma vitória estupenda. Mas a maior chance é que seja uma derrota miserável.

Porém há ainda quem sinta falta das vitórias extravagantes ou pelo menos do alívio de saber que acabou de deixar uma quantidade monumental de trabalho para trás. Muitas equipes que trabalham às cegas durante muito tempo costumam comemorar estrondosamente as entregas. Mesmo quando são tremendos fracassos comemorar é natural simplesmente porque todos acabam de se livrar de um fardo bastante pesado. Com ciclos curtos, esse sentimento se perde. Não faz muito sentido comemorar a entrega de uma semana de trabalho. Ao fim de dois meses, uma equipe com ciclos de uma semana provavelmente vai ter uma vitória acumulada muito maior do que uma equipe com um único ciclo de dois meses. Apesar disso, a segunda vai comemorar muito mais.

Usar prazos curtos para as entregas é uma boa forma de garantir que elas sejam vitoriosas. Pequenas vitórias, mas vitórias.

A grandiosidade do pequeno

O mundo todo é formado a partir de coisas pequenas. Não importa quão grande seja a casa daquele novo figurão, ela precisa ser construída tijolo a tijolo. Enxames são feitos de pequenas abelhas, países são feitos de cidadãos e mercados são feitos de negociantes. No entanto, o resultado final do conjunto em todos os casos é um conglomerado grandioso e costuma ser considerado uma entidade única por vários motivos, que vão do retórico ao pedagógico. Fica difícil ver a floresta inteira quando se está no meio das árvores. Para entender o todo, precisamos ignorar por um momento as partes e analisar o conjunto como uma entidade única.

Isso é importante em muitas situações e não há como negar que o homem só chegou onde está por ter desenvolvido essa capacidade. Mas estamos acostumados a partir das partes para o todo. Estamos acostumados a sintetizar. O perigo mora no caminho inverso: tratar o todo como um entidade indivisível e esquecer que para mudá-lo é preciso dispensar muita atenção para as partes.

Quando uma empresa precisa melhorar sua capacidade de produção ou velocidade de resposta, uma das piores coisas que se pode fazer é tentar projetar e aplicar uma metodologia qualquer que trate a organização inteira como uma grande equipe. Tudo que uma grande organização menos precisa é de uma metodologia para uma equipe de centenas de pessoas. O que ela precisa na verdade é de centenas de equipes de poucas pessoas. Não é preciso achar uma metodologia gorda e formar uma equipe gigante, mas formar equipes pequenas e arrumar metodologias enxutas.

Necessariamente nesta ordem.

Todo mundo já ouviu falar que formas ágeis de trabalho funcionam melhor para equipes pequenas e há quem prefira abordagens mais peso-pesado justamente por este motivo. O interessante é que isto não é uma fraqueza. Qualquer abordagem para coordenação de pessoas funciona melhor com equipes pequenas. Portanto, ter equipes grandes não é motivo para evitar uma abordagem ágil. Os grupos de trabalho simplesmente deveriam ser menores. Grupos pequenos conseguem se organizar e comunicar-se mais facilmente do que grupos grandes simplesmente porque há menos gente para coordenar. Se você tentar reunir mais de duas pessoas para escolher um único prato em um restaurante novo, vai saber do que estou falando.

Equipes pequenas costumam vencer as grandes no quesito adaptabilidade. O pequeno e simples é mais rápido para se adaptar. Bactérias, por exemplo, são extremamente adaptáveis justamente por serem criaturas bem simples. São capazes de se reproduzir e evoluir tão rapidamente que os médicos precisam evitar prescrever os mesmos antibióticos por períodos prolongados para uma mesma população a fim de evitar que elas se acostumem à droga e evoluam para algum tipo de super-bactéria resistente à medicação. A capacidade de adaptação delas é tamanha que “períodos prolongados” aqui são medidos no máximo em algumas dezenas de anos, ao contrário dos vários milhares de anos necessários para a evolução de organismos mais complexos como o homem. O mesmo ocorre com equipes pequenas. Na presença de uma adversidade ou mudança de ambiente, elas podem mudar de rumo muito mais rápido que uma equipe com algumas dezenas de pessoas.