Por que projetos de desenvolvimento de software atrasam?

Aviões atrasam, noivas atrasam e até a mestruação da sua namorada atrasa! Com projetos de software não poderia ser diferente!

Mas espera, o que significa “estar atrasado”?

Segundo alguns dicionários: “Falta de pontualidade no cumprimento de uma obrigação ou compromisso.”

Abaixo, faço questão de citar alguns exemplos do dia-a-dia:

- O trem está atrasado devido a um procedimento de manutenção emergencial nos trilhos.
- Devido aos fortes ventos, o horário de decolagem foi atrasado em 2 horas.
- A mestruação da namorada de Oscar está 3 semanas atrasada.

O mais interessante de tudo é como chegamos a conclusão de que estamos de fato atrasados. No caso dos trens e aviões, possívelmente levaram algumas viagens em diferentes tipos de clima, horários e estações do ano para que fosse construida uma base histórica suficientemente assertiva que pudesse auxiliar na tarefa de prever horários de chegada e partida. Da mesma forma aconteceu com a mestruação, quanto tempo leva para estabilizar um ciclo?

Esse tipo de estimativa é conhecida como análoga, sendo inclusive um dos tipos de estimativa mais utilizados pelo guia PMBOK e possívelmente muito interessante em diversos tipos de projetos de outras naturezas diferentes de software.

O problema é simples: “Quantas vezes já desenvolvemos um projeto de software com o mesmo escopo, com a mesma tecnologia e com a mesma equipe?”.

Logo, estamos em desvantagens se compararmos nossa difícil atividade de desenvolver software em relação a outras áreas como a engenharia, extremamente rica em dados históricos.

Já parou para pensar em quantas vezes pegamos caminhos errados em termos de tecnologia e precisamos voltar atrás? Será que isso é comum em uma obra? Imagina um pedreiro destruindo constantemente uma parede inteira por conta de um tijolo incompatível?

Se estar atrasado significa faltar com a pontualidade, como podemos determinar o que é essa tal pontualidade?

Lembre-se que nunca estivemos lá antes.

O conselho aqui é: Cuidado com estimativas realizadas muito cedo em projetos de software, possívelmente ela será muito elastica.

Com o passar do tempo, sem dúvida é possível estabilizar a velocidade pelo conhecimento cada vez maior do tipo de escopo que está sendo trabalhado, tecnologia sendo utilizada e até mesmo com o aumento do entrosamento da equipe.

Conclusão: Como fica a análise de viabilidade? Sim, invista em gerenciamento de riscos e reserve uma boa margem de custos. Projetos de software podem ser bem arriscados e custaria igualmente caro tentar prever e estimar todo o tipo de atividades ao ponto de mitigar tantos erros de estimativa.

Até a próxima!

Sprint Zero – #ScrumSeries

Recentemente saiu um artigo na InfoQ onde alguns autores respeitados defendiam a entrega constante de valor de negócio mesmo na primeira sprint do projeto.

Um dos argumentos principais estava ligado a distribuição das atividades ligadas a arquitetura ao longo do projeto e dessa forma balancear negócio e tecnologia.

Já acompanhei o início de muitos projetos e vivenciei sérios problemas ligados a falta de infraestrutura básica como a automação de build e por conta disso falta de integração contínua.

Entendo que entregar em uma sprint apenas o arquivo de build e um projeto vazio, no entando integrando contínuamente de certa forma não agrega muito. Entretanto, devemos evitar ao máximo manter as janelas quebradas por muito tempo.

O débito técnico mata o projeto aos poucos e juntamente com a falta de automação e baixa visibilidade podem levar a equipe diretamente para o precipício.

Qual é o problema com as equipes multi-disciplinares? – #ScrumSeries

Em tempos de Scrum em alta, o termo equipe multi-disciplinar ficou muito em evidência, mas parece que acaba quase sempre sendo ignorado.

Uma equipe multi-disciplinar é diferente de uma pessoa multi-disciplinar. A primeira é formada por um conjunto de pessoas, cada uma com sua habilidade específica, como por exemplo: design gráfico, desenvolvimento de software, manuais, testes e até implantação. Enquanto isso, a segunda é aquela que faz tudo isso ao mesmo tempo.

O grande problema é que apesar de parecer simples colocar todo tipo de habilidade dentro da mesma equipe, na prática é algo quase impossível para a realidade da maioria das empresas. A maioria delas possui mais de um produto para desenvolver e dar suporte e muitas vezes esse número de produtos é maior que o número de pessoas, levando naturalmente a impossibilidade em dedicar uma pessoa de forma integral para um projeto.

O reflexo disso é que a equipe do projeto acaba sendo composta de fato apenas pelos responsáveis pela codificação. Com isso é normal ver os estoques de código em alta enquanto aguardam para serem testados, aprovados pelo pessoal de negócio, revisados pelo designer e até implantados pela equipe de deploy.

Particularmente acredito que tem algo muito errado nesse ponto. Ninguém está de fato entregando software desse jeito!

“Software funcionando” é a medida primária de progresso, não “Software no repositório”, independente se está funcionando ou não.

Goldratt já dizia em sua teoria das restrições que toda organização tem menos uma restrição que limita a performance do sistema. Me arrisco a dizer que em muitas delas a restrição está em não ter um olhar sistêmico que consiga revelar de fato o que está impedindo o software de entrar em produção.

Vou explorar em um próximo post a idéia das equipes multi-disciplinares virtuais, que em alguns cenários pode ajudar a atenuar o problema da falta de multi-disciplinaridade nas equipes.

Domain-Driven Design em algumas palavras

Todo software é desenvolvido por meio da materialização do conhecimento e este campo de ação, conhecimento e influência também é conhecido como o domínio de um software.

Existe uma grande distância separando quem realmente entende com profundidade os detalhes de um domínio, também conhecidos como Domain Experts, e quem domina a tecnologia e a habilidade técnica necessária escrever o código.

Domain-Driven Design, ou apenas DDD, não é uma metodologia ou tecnologia, mas sim uma forma de aproximar Domain Experts e desenvolvedores, alinhando e comunicando de forma efetiva dados, fatos e expectativas a respeito do domínio e fazendo com que sua integridade seja mantida e protegida no coração do software.

Referências e recomendações:

Domain-Driven Design Community

http://domaindrivendesign.org/

Eric Evans – Domain-Driven Design

http://domaindrivendesign.org/books/evans_2003

Abel Avram e Floyd Marinescu – Domain-Driven Design Quickly

http://domaindrivendesign.org/books/avram_marinescu_2007

Dan Haywood – Domain-Driven Design using Naked Objects

http://domaindrivendesign.org/books/haywood_2009

Product Backlog – #ScrumSeries

Infelizmente, muita gente a considera e utiliza o Product Backlog apenas como uma espécie de estacionamento de requisitos ou caixa de sugestões, que ficam enfeitando alguma parede ao redor da equipe do projeto.

É importante entender que o Product Backlog é um dos artefatos mais importantes de um projeto que, supostamente, utiliza Scrum e que ele só faz sentido se estiver corretamente priorizado e estimado durante todo tempo.

Não é muito difícil ver equipes realizando longas e desgastantes reuniões de planejamento de sprint, perdendo tempo com sessões de braintorming para tentar definir o que deverá ser feito na sprint. A reunião de planejamento, em sua primeira etapa, serve para que a equipe possa buscar um entendimento profundo do que foi selecionado, de acordo com a release. Se for necessário discutir o que deveria ser selecionado, o tempo vai ficar curto.

Por isso é fundamental realizar traçar releases e realizar Story-Writing Workshops em períodos regulares para que o Product Owner possa garantir entregas consistentes e alinhadas com os objetivos estratégicos para o produto. É papel do ScrumMaster ajudar o Product Owner, garantindo que ele cuide da evolução do Product Backlog. Só assim será possível evitar que o time perca tempo durante as reuniões de planejamento de sprint.

No próximo post, vou explorar técnicas de Priorização de Product Backlog.

A importância da Reunião Diária – #ScrumSeries

O principal objetivo da reunião diária está relacionado ao planejamento tático, momento em que o time planejará o seu dia de trabalho. É uma grande oportunidade para alinhar a visão de toda a equipe em relação as suas metas, definindo qual será a estratégia utilizada e detectando possíveis falhas nesta estratégia. A idéia é criar colaboração, deixando a equipe mais coesa, motivada e segura de que está indo no caminho certo.

Um dos modelos mais utilizados para a facilitação e condução desta reunião é o famoso: “O que eu fiz desde a última reunião diária?“, “O que eu farei até a próxima reunião?” e “Existe alguma coisa me impedindo?“.

Infelizmente, existe uma forte tendência nas equipes em se focar apenas na resposta da primeira pergunta, “Eu fiz … desde a última reunião”. Dessa forma, a reunião se transforma em uma monótona e pouco promissora verificação de progresso, apenas contabilizando ou no máximo se conformando em relação aos problemas que já aconteceram.

Com o foco na resposta da segunda pergunta, “Eu planejo fazer … até a próxima reunião?”, se abre uma oportunidade de colaboração e suporte por parte do time em relação ao que cada um pretende realizar durante seu dia de trabalho. É um momento oportuno para questionar o valor de uma atividade, sua contribuição para cumprir o critério de aceitação de uma estória ou mesmo propor auxílio como por exemplo uma sessão de pair programming para resolver um determinado problema.

Ainda pior é não realizar a reunião diária. O reflexo acaba sendo uma sensação de abandono e desmotivação da equipe que já não acredita mais no cumprimento das próprias metas.

Seguem abaixo algumas desculpas comuns (experiência própria) que devem ser evitadas:

Não produzimos nada hoje! Pra que realizar a reunião diária?
Um dos membros da equipe está doente, não seria melhor deixar a reunião diária para outro dia?
Esquecemos a reunião diária! Como isso foi acontecer?
Não temos tempo para a reunião diária! O projeto está muito atrasado!

Se não produzimos nada hoje, o que podemos fazer para sermos produtivos daqui pra frente? Se um dos membros está doente, como podemos fazer para suprir a sua falta? Se estamos esquecendo a reunião diária ou mesmo não temos tempo para realizá-la é sinal de que ela não está agregando valor e se isso está acontecendo a equipe deve reavaliar a forma como ela está sendo conduzida.

Aproveitar as reuniões diárias para fortalecer a comunicação e a confiança entre a equipe, criando uma cultura de falhar o mais cedo possível, evitando insistir em desperdícios, é um grande passo rumo a um processo de desenvolvimento maduro e bem sucedido.

“In preparing for battle I have always found that plans are useless, but planning is indispensable.” (Dwight D. Eisenhower)

Não deixe de comentar sobre a sua experiência com reuniões diárias!

Vidente ou desenvolvedor?

Desenvolver software é uma atividade criativa, envolve aprender sobre algo novo e que na maioria das vezes nunca fizemos antes. Ao longo do projeto, muitas descobertas são feitas, diferentes pontos de vista surgem (muitas vezes conflitantes) e as famosas mudanças começam a acontecer! Entretanto, infelizmente existe uma obsessão em traçar o futuro logo no início do projeto justamente para tentar evitar que as coisas mudem, ou melhor, evoluam. Ao fazer isso acabamos limitando conclusões importantes, antecipando um estoque de funcionalidades que podem não ter tanto valor no curto prazo e assim reduzindo as chances do projeto ser bem sucedido!

É importante tomar muito cuidado ao planejar o início de um projeto ou até mesmo pensar em releases de longo prazo. Entende-se como release um conjunto de funcionalidades que fazem muito sentido juntas e configuram um marco importante ou versão mínima de lançamento de um determinado projeto. Entretanto, ao antecipar e reconhecer a existência dessas releases, tendemos a respeitá-las como se fossem uma verdade absoluta. Quanto mais longe for essa visão de futuro, mais distante poderemos estar de repensar nossos conceitos sobre o software. A idéia de ter um plano já traçado nos leva a segui-lo, dando um certo conforto. Voltando ao assunto, desenvolvimento é aprendizado, é criatividade e principalmente não permanecer na zona de conforto.

Gosto da abordagem de dar pequenos passos, um de cada vez, olhando para trás e vendo o caminho percorrido, aprendendo com ele! É como andar numa estrada com neblina, cada curva que surge nos obriga a tomar uma nova ação. Dessa forma, todos os envolvidos no projeto precisam rever seus conceitos entrega após entrega (por isso é importante que elas sejam constantes), podendo mudar completamente o rumo das coisas. Sim, é trabalhoso e menos previsível. Mas como não somos videntes e sendo assim previsões não fazem parte do nosso trabalho, deveríamos pensar menos no futuro! Gosto daquela abordagem de: “E se o mundo estivesse acabando, o que você é a coisa mais importante que você implementaria no seu sistema?”.

A idéia de ter uma longa lista de coisas a se fazer dá uma sensação de incapacidade, de fato é! É importante entender nossa capacidade, se ajustar a ela. Lembrando que se tudo é prioritário então provavelmente nada deve ser. Uma coisa é certa ou deveria ser: “Se algo for muito importante, você ou o seu cliente vão lembrar!”. Ser ágil é responder a mudanças, melhor ainda é viver delas! Vamos deixar para os engenheiros civis o dever de saber quantos andares o prédio terá antes mesmo dele sair do papel, afinal, é preciso projetar seu alicerce! Nos deixem com nossos clientes que não sabem o que querem! Assumir que não sabemos o que queremos, tendo a certeza que isso virá naturalmente ao longo do tempo, é primeiro passo rumo ao sucesso no desenvolvimento de software.

O Poder do Silêncio

Sempre que chego em um ambiente de desenvolvimento muito quieto, esses onde todos ficam o dia todo com seus fones de ouvidos (nada contra os fones) sem trocar uma palavra, me dá uma sensação um pouco estranha, de que algo pode estar errado ali. O silêncio e o clima do ambiente de desenvolvimento acabam revelando muito sobre como uma empresa desenvolve seus softwares e valoriza seus funcionários.

O individualismo quase sempre leva a uma estrutura egoísta de trabalho, onde cada um se preocupa apenas com seus próprios problemas, sem se dar conta que estes pertencem a todos e sem fazer idéia do que está acontecendo com o restante do projeto. Desta forma o time não colabora, não busca os mesmos objetivos e acabam transformando o desenvolvimento de software em uma atividade monótona e desmotivante.

Em tempos de fábricas de software, as atividades nunca foram tão individualizadas. Muitas empresas ainda veêm uma equipe de desenvolvimento como um conjunto de recursos, substituíveis facilmente, prontos para seguirem os guidelines, padrões e normas que juntos ajudam a eliminar qualquer forma de inovação que poderia emergir.

A comunicação é a ferramenta fundamental para ter sucesso em qualquer projeto. Através dela é possível transformar complexidade em realidade, unir o time e fomentar a motivação.

Tradução: Dissecting Technical Debt

O termo “débito técnico” foi definido por Ward Cunningham e descreve a dívida que a equipe de desenvolvimento assume quando escolhe um design ou abordagem fácil de implementar no curto prazo mas com grande impacto negativo no longo prazo.

Alguns agilistas opinaram sobre o que deve ser considerado débito técnico e como poderia ser classificado:

Martin Fowler sugeriu a seguinte definição para débito técnico,

Débito técnico é similar a débito financeiro. Assim como o débito financeiro, o débito técnico exige o pagamento de juros. Estes vem na forma de esforço extra, que devem ser pagos em desenvolvimentos futuros por conta da escolha de um design mais rápido e de baixa qualidade. Nós podemos optar por continuar pagando estes juros ou quitar de uma vez a dívida fazendo uma refatoração, transformando um design de baixa qualidade em um design melhor. Apesar dos custos para saldar a dívida, nós ganhamos reduzindo os juros no futuro.

Steve McConnell classificou o débito técnico em dois tipos,

  • Sem querer – Desenvolvedores junior escrevem código de baixa qualidade por conta de sua inexperiência técnica.
  • Intencional – A equipe faz uma decisão consciente para otimizar para o momento atual e não para o futuro, fazendo algumas escolhas de design que podem ser uma maneira rápida e de baixa qualidade para resolver a situação.

Uncle Bob adiciona que muitas vezes um código bagunçado é considerado débito técnico. Mas isso está errado! Segundo ele,

Bagunça não é débito técnico. Bagunça é só bagunça. Decisões que geram débitos técnicos se baseiam em restrições do projeto. Elas são arriscadas, mas podem trazer beneficios. A decisão de fazer uma bagunça no código nunca é racional, é sempre baseada na preguiça e na falta de profissionalismo e não tem chances de ser pagas no futuro. A bagunça é sempre uma perda.

Uncle Bob sugere que débito técnico cria a necessidade de limpeza no codigo, assim como a necessidade de ser mais disciplinado quando assumir um grande débito. Ele adiciona que uma vez que a equipe decida assumir um débito técnico, se torna ainda mais importante manter o código completamente limpo. Senão, a situação poderá se agravar e pagar a dívida pode ser um grande desafio.

Martin Fowler aponta que bagunça também é um débito técnico embora de natureza diferente. Ele descreve a bagunça como reckless debt (débito irresponsável) a qual resulta em desafios ainda maiores se comparados com um prudent debt (débito prudente) baseado em uma situação pensada. Além disso, ele classifica o débito técnico como de propósito e sem querer para completar a lista.

Martin cita os seguintes exemplos de classificação de débitos técnicos:

Reckless and Deliberate (Irresponsável e de propósito): O time não tem tempo para o design e utiliza uma solução rápida e com pouca preocupação com a qualidade.

Prudent and Deliberate (Prudente e de propósito): O time precisa entregar o produto agora com todas as limitações conhecidas e assume de maneira pró-ativa as conseqüências.

Reckless and Inadvertent (Irresponsável e sem querer) – O time não tem consciência dos principios básico de design e então nem sequer imagina a bagunça que estão adicionando.

Prudent and Inadvertent (Prudente e sem querer) – Isso é verdade para times com excelentes arquitetos. Eles fornecem uma solução que agrega valor ao negócio, mas depois de completar a solução, eles entendem que a abordagem de design poderia ter sido melhor.

Desta forma, ter um débito técnico em um projeto é normalmente inevitável e deve ser considerado como sendo uma expectativa. A chave está em ter certeza de que o time não está introduzindo débitos irresponsáveis que contribuem para bagunçar o código e são muito difíceis, senão impossíveis de lidar.

Traduzido do original no site do InfoQ no link: http://www.infoq.com/news/2009/10/dissecting-technical-debt

Amadurecendo o workflow do Projeto

Atualmente, muitas empresas estão adotando metodologias ágeis e em especial o Scrum com o objetivo de melhorar a gestão de seus projetos de software. No inicio, os projetos utilizam um workflow simplificado para sinalizar o andamento da iteração. Esse fluxo normalmente é composto por 3 estados:

  • TO DO: Estórias selecionadas para o backlog da iteração que estão aguardando para serem iniciadas.
  • IN PROGRESS: Estórias em andamento, sendo executadas pelo time no momento.
  • DONE: Estórias prontas para serem entregues.

Segue abaixo um exemplo de um Scrum board com um fluxo simplificado:

Com o passar do tempo, surge a necessidade de amadurecer esse workflow, mapeando ações técnicas e de qualidade que reunidas formam o conceito de Definição de Pronto (ou Definition Of Done).

A Definição de Pronto reúne os critérios que o time deve seguir para que uma funcionalidade possa ser realmente considerada pronta, não só técnicamente mas também com qualidade. Essa definição é composta por uma lista de ações como: escrever testes de aceitação, codificar, revisar o código, validar o que foi feito com o product owner, fazer o deploy no servidor de produção ou qualquer outra coisa que precise ser feita para que a funcionalidade possa ser entregue atendendo as necessidades de negócio. Com a evolução do projeto, é importante estar sempre observando e adaptando esses critérios para que eles possam acompanhar a realidade projeto, estando alinhados com as expectativas do cliente.

Os problemas surgem quando algumas ou muitas dessas ações não são executadas corretamente e assim muitas estórias consideradas prontas pela equipe acabam tendo problemas na hora da revisão com o product owner, não sendo aceitas. Um fator que contribui para isso é a utilização de estados nebulosos no workflow do projeto. Decompor o estado “in progress” em estados que representem importantes ações da Definição de Pronto aumenta a visibilidade do time sobre qual etapa do processo está sendo executada e facilita a identificação e remoção de gargalos, aumentando a eficiência do processo.

Segue abaixo um exemplo de Scrum board com um workflow contendo os estados de análise, codificação, testes e deploy :

Para manter o fluxo constante, é importante evitar o acumulo excessivo de estórias em cada estado. Estes acumulos criam estoques que diminuem o ritmo e a freqüência de entregas, incentivando um comportamento multitarefa que contribui para um fluxo ineficiente e com desperdícios.

Segue abaixo um exemplo de Scrum board com acumulo de estórias em andamento e com poucas realmente entregues:

O número de estórias em cada estado é denominado WIP (Work in Progress). Limitar o valor do WIP contribui para impedir a sobrecarga do sistema e faze-lo trabalhar com a sua capacidade real. Assim, as demandas começam a se adequar a capacidade de produção do sistema e não o contrário. Além disso, a ocorrência de impedimentos acaba causando uma interrupção no processo (ou stop the line), afetando o trabalho de toda a equipe e fazendo com que os impedimentos sejam resolvidos rapidamente.

Para entender melhor sobre a dinâmica da teoria das filas que a limitação do WIP proporciona é fundamental acessar uma simulação completa do funcionamento do kanban em: http://blog.crisp.se/henrikkniberg/2009/06/26/1246053060000.html

Segue abaixo um exemplo de Scrum board com limite do WIP. Dessa forma, nunca poderá haver mais de duas estórias em andamento, aumentando a colaboração da equipe e a utilização de técnicas como o pair programming. Lembrando que esses valores variam dependendo do objetivo e quantidade de pessoas na equipe. A alteração dessas variáveis pode ajustar o processo, afetando a produtividade do sistema.

Dessa forma é possível criar um workflow que prioriza a visibilidade do trabalho em execução, evidenciando impedimentos e gargalos, além de manter o sistema estável e constantemente otimizado. Com isso é possível entregar com mais freqüência e com mais qualidade, melhorando a percepção do cliente e criando um ambiente de desenvolvimento melhor para todos.

Segue abaixo alguns links para blogs importantes que falam sobre o assunto:

http://www.limitedwipsociety.org/

http://blog.crisp.se/henrikkniberg/

http://leansoftwareengineering.com/

http://www.alissonvale.com/englishblog/

http://damonpoole.blogspot.com/

Segue também uma lista de ferramentas e padrões utilizados no processo:

  • Value Stream Mapping
  • Visual Management
  • Pull System & Single Piece Flow
  • Limited WIP
  • Buffers & Queue Limits
  • Classes of Service
  • Leveling Work
  • Two tiered Systems (Expand/Collapse)
  • Swimlanes/Expediting
  • Triggers
  • Priority Filters
  • Perpetual Multivote
Seguir

Obtenha todo post novo entregue na sua caixa de entrada.