Resistência à Mudanças

As metodologias ágeis enfrentam muitas resistências no mercado. Muitas vezes a resistência está em nós mesmos! 

Esse post causou uma boa polêmica e levantou vários pontos que o mercado utiliza para não adotar agilidade (Vejam os comentários aqui). Conheço o Fábio, e ele é um arquiteto de muitíssima competência com várias certificações e demonstra bem o que muitas empresas pensam a esse respeito. Porém uma opinião tem que ser formada quando se conhece bem os opostos. Muitas perguntas passam por nossa cabeça quando a gente depara com um novo paradigma, é normal!

Como estimar prazos em uma metodologia ágil? Como fica o contrato? Como garantir implementar funcionalidades dentro do escopo?

Um dos grandes ganhos da metodologia ágil com certeza é estimativa de prazos. O Scrum tem várias técnicas para estimar um prazo conciso. Mas como estimar? O Scrum tem o Planning Poker.

 

E se a estimativa falhar? É mais difícil isso acontecer pois os sprints (iterações) devem ser curtos, mas se acontecer o Scrum tem o Sprint Retrospective, Sprint Review. 

Como aprender com os erros? Sprint Backlog atualizado. Como manter o time auto-motivado? Daily Scrum. Como fazer códigos melhores? Pair Programming.

O assunto é muito rico. Tem muitos cursos bons no mercado. Para quem gosta de auto-estudo eu recomendo os livros:

 

Alguém já pensou nos problemas que a gente enfrenta. Sempre ouvimos a frase “Não reinventar a roda”.

Apenas mais um ditado que gosto muito:

“Um tolo erra e insiste no erro

Um inteligente aprende com os próprios erros

Um gênio aprende com os erros dos outros”

Divisão de Responsabilidades

Quando eu falei sobre divisão de responsabilidades no post anterior eu não quis dizer uma pessoa fazer o trabalho de todos, muito pelo contrário! E para uma equipe maior que umas 9 pessoas pode ser impraticável algumas técnicas do Scrum, por exemplo o Daily Scrum que tem o objetivo de ser rápido. Mas quando ocorre um time tão grande assim? Não é impossível ter muitas pessoas num projeto. Eu particularmente já participei de um time de 11 desenvolvedores. Nesse caso talvez algumas técnicas do Scrum me ajudasse, mas não todas! Porém a maioria das vezes a equipe não é tão grande, então quanto mais técnicas usar, melhor!

Mas vamos pensar um pouco. Um problema que acontece muito nos projetos atuais é o software final não sair da maneira que o cliente esperava, e aí ocorrem os retrabalhos. Por que isso acontece tanto? Não quero generalizar, só vou dar um exemplo. Ocorre porque no levantamento do projeto os analistas de negócio fazem toda a documentação e passam para uma fábrica de software implementar. Os desenvolvedores são cobrados por prazos e muitas vezes não lêem todas as 50 páginas do documento e fazem da forma que entenderam podem interpretar de maneira erronea, a não ser que exista um documento de Visão que não permita esse mal entendimento. Eles não participaram das reuniões com o cliente não sabem o escopo do projeto o que facilitaria o entendimento e possibilitaria ter uma visão macro do projeto. Mesmo se o conhecimento for passado do analista de requisitos para o desenvolvedor por meio de uma conversa, não será tão bom como o próprio cliente passar o conhecimento, pois esse último é o que realmente entende do negócio. As vezes um intermediário pode causar o problema de telefone sem fio. Daí quando o projeto está quase acabando já é tarde demais. Comentei sobre isso nesse post.

Uma metodologia ágil deve dizer que o cliente tem que estar sempre próximo do time, e quanto mais desenvolvedores participarem das reuniões, sobre os requisitos por exemplo, é melhor. No scrum existe os papéis de Product Owner (pode pensar no cliente do exemplo citado), o Time, e o Scrum Master. Isso muitas vezes é o suficiente.

Devemos ter testers? Sim, mas se o time trabalhar com TDD do Extreme Programming pode ser que não precise.

Podemos ter analistas de negócios? Sim, desde que não seja um intermediário.

IBM adotando Metodologia Ágil?

Estive dia 18/06 no evento IBM Development Conference 2008 e quero comentar sobre a estratégia que a IBM vem tendo com metodologias ágeis e processos. Espero lembrar de bastante coisa para poder compartilhar as idéias.

O evento começou com um filme de computação gráfica com a intenção de mostrar os problemas reais de desenvolvimento de software. O filme foi apresentado em vários capítulos divididos entre as palestras. Os heróis, ainda sem seus poderes, eram o desenvolvedor, a tester, o gerente de projeto, o arquiteto etc. Eles começaram a ter os problemas que a gente não conhece no dia-dia dos projetos por exemplo apagar incêndios! E começaram a ser ameaçados por inimigos, outros personagens gráficos, que representam os problemas reais que aparecem nos projetos. E ameaçaram dizendo aos heróis: Salvem o seu dia de trabalho se puderem, se é que conseguirão salvar seus trabalhos. Daí apareceu um cara com uma testa enorme, um tipo de oráculo. Esse cara surgiu para acordar os heróis pra vida e ajudá-los a salvar o dia de trabalho e depois….

Não peguei o final da estória! Se alguém souber pode comentar o post. Apesar que está um pouco óbvio quais são as ferramentas que eles vão usar no final do filme. Agora vamos ao que interessa.

A maior aposta da IBM está sendo na plataforma Jazz, uma integração em tempo real de pessoas, processos e ferramentas. O nome é uma metáfora a um conjunto musical mesmo. Essa é uma iniciativa de trabalho em conjunto para entregar mais VALOR e melhor performance para um investimento de software. O Jazz não é nada novo, já faz uns dois anos de vida, mas está na versão beta e eles pedem para a comunidade contribuir e cadastrar idéias de melhorias, que vai ter um desenvolvedor lá para implementar.

A um tempo atrás eu falei sobre a importância de uma Metodologia Ágil, e a IBM não quer ficar para trás. Eles estão adotando internamente uma Engenharia de Software Ágil chamada IRUP, uma abreviação de IBM Rational Unified Process.

Eles se mostraram muito preocupados em unir desenvolvimento ágil com a governança, como um “Investimento disciplinado”.

“Tailoring governance is a progress.”

Com uma Governança adequada eles citaram:

  • É mais fácil ficar aderente aos padrões
  • Detecção de resolução de defeitos antecipadamente
  • Melhor previsibilidade dos projetos.
Uma frase interessante foi:
“Muitos clientes só sabem o que querem quando eles vêem o que não querem.”

Porque a IBM está falando em agilidade? A própria IBM concorda que RUP + CMM trouxe muita coisa que não era realmente necessário para o desenvolvimento de software. Eles falaram:

“Os clientes que usam RUP e CMM estão na verdade fazendo mais processo do que eles realmente precisam.”

“Deve-se fazer menos reuniões e relatórios”

“Ter um maior aproveitamento dos especialistas e do conhecimento.”

Eles falaram também que:

“Software funcionando é mais importante que o processo!”

 

Uma coisa dita em uma das palestras sobre agilidade foi focar em ferrementas, e não regras. Será que isso tem o mesmo significado do que fala o Manifesto Ágil em que pessoas e interações são mais importantes que processos e ferramentas?  

Para trabalhar com agilidade basta post-its! Apesar que gostei da experiência de usar o Mingle com template para Scrum. Só que a IBM se mostrou preocupada com equipes distantes como, por exemplo, desenvolvedores no Brasil, testers na Índia e gerentes de projeto na Europa. E para isso propôs uma ferramenta para gestão de processos ágeis: O Rational Team Concert. Tráta-se uma ferramenta de gerência de metodologia ágil e é também uma gerência de build. Ela foi a primeira ferramenta construída totalmente na plataforma Jazz. Segundo eles é uma ferrameta muito fácil de instalar, roda no tomcat e pode ser customizado com a metodologia ágil de preferência (IRUP, Scrum, Open Up…)

Os times ágeis, para a IBM, devem trabalhar com desenvolvimento de software dirigido a mudanças e haver uma integração contínua. A produtividade deve aparecer no primeiro dia, pois o início do projeto deve começar em dias e não em semanas. Deve haver uma redução do tempo até o primeiro Demo. Um exemplo foi:

“Microsoft gera um build cada 3 anos.

O Flickr faz deploy todos os dias.”

Alguns dados que eles passaram:

  • 37% dos usuários estão satisfeitos com a velocidade do desenvolvimento dos projetos.
  • 50% dos projetos terceirizados performam abaixo do esperado.
  • 42% dos usuários acham a qualidade satisfatória.

Teve uma palestra sobre Testes de Software e Gerenciamento de Qualidade, o que a IBM ainda considera um débito em relação ao mercado. Por isso eles estão lançando o Rational Quality Manager. Essa e outras ferramentas é que compões o Jazz. Mas segundo eles será possível integrar com outras ferramentas de mercado, por exemplo o Bugzilla.

Nenhuma das palestras que participei falaram de XP ou Scrum. O que eu mais ouvi sobre métodos ágeis foi sobre desenvolvimento em iteração, o que já existia no RUP. Esse IRUP me pareceu um RUP um pouco melhorado, com menos documentações e muita ferramenta. 

Agora tenho a seguinte dúvida: Será que a metodologia ágil da IBM trará os benefícios que Scrum + XP trás para nós? Os heróis do filme da animação gráfica eram em 6, ainda não é muita divisão de responsabilidades para um time ágil?

Escalabilidade != Performance

A Escalabilidade é um requisito não funcional de arquitetura que deve ser considerado em todos os projetos porém, dependendo das necessidades do cliente (requisito funcional) e da quantidade de usuários, a escalabilidade pode um peso maior ou menor dentro do projeto.

Muita gente confunde escalabilidade com desempenho (performance) mas são duas coisas muito diferentes, apesar se um influenciar o outro. Performance é a capacidade de atender requisições dos usuários em tempo de processamento e consumo de memória aceitáveis conforme as necessidades do cliente. Já a escalabilidade é a capacidade de manter a disponibilidade e o desempenho a medida que a carga transacional aumenta. Você pode ter um sistema altamente performático em uma máquina mas que é impossível de escalar em uma arquitetura de cluster, por exemplo. Pensar em escalabilidade não é somente pensar em aumentar máquina. É pensar em IO, memória, requisição, banco de dados e assim por diante. Por exemplo, uma aplicação web que guarda muitos dados na sessão pode ser bem performática, mas se essa aplicação passar a ser usada como um web site, com milhares de usuários, a quantidade de informação na sessão (memória do servidor) tornará o sistema lento! Um HttpSession é muito difícil de escalar se for fazer uma estratégia na mão. Nesses casos uma estratégia de cache distribuído, como o memcached, poderia resolver o problema.

Tive uma experiência recente com uma aplicação web que estava apresentando problema de performance, então precisei fazer uma análise para descobrir a causa. Infelizmente essa aplicação também tem problema de manutenabilidade e nessas horas os autores nunca trabalham mais no projeto e não deixaram o endereço da casa deles para quem for dar manutenção! 🙂

Analisando o código, de cara já vi que teria problemas pois o sistema não tem testes unitários. Com certeza haveria a necessidade de fazer refatorações e nem ao menos posso garantir que não vou “quebrar” o software. Os testes de unidade e/ou de integração são tão importantes quanto o projeto em si pois são eles que garantem a qualidade do software. Um programador profissional deve escrever testes, como já disse Phillip Calçado aqui! Como não há testes, a refatoração foi dividida em sprints bem curtos de no máximo uma semana. Já que o projeto está em produção, é interessante construir testes de falha e depois testes de sucesso, pelo menos para as funcionalidades mais importantes. O ideal seria que a equipe tivesse trabalhado com TDD.

Essa aplicação, escrita em Java, apresentava problemas arquiteturais de performance mesmo com uma infra poderosa com vários clusters e load balancing, e consequentemente afetou a escalabilidade pois o aumento transacional causou indisponibilidade do sistema. Portanto, com o aumento de usuários, entrada de novas funcionalidades e crescimento de registros no banco de dados, a aplicação começou a travar e apresentar muitos problema de lentidão.

Antes de começar a fazer qualquer alteração precipitada eu baixei o JProfiler para tirar uma primeira análise. A ferramenta é boa mesmo! Monitorar consumo de memória, tempo de processamento, hotspot, trabalho do garbage collection, consultas demoradas no banco de dados etc. É uma boa prática monitorar frequentemente as aplicações com um profiler para saber como está indo o desenvolvimento, evitando gargalos desnecessários. Essa prática também evitaria otimizações prematuras, como disse Joshua Bloch aqui. Por exemplo, muita gente altera concatenação de String para StringBuffer, mas nem sabe que internamente a concatenação de string seria transformada em StringBuilder pelo java.

Voltando à aplicação, de nada adiantaria sair alterando o código se o problema estiver no banco de dados. Precisei criar índices das tabelas e com a ajuda do JProfiler isso ficou bem fácil. Já na parte da aplicação, a ferramenta também me ajudou a encontrar problemas como:

  • Excesso de instanciação de objetos dentro de loops bastante grandes. Muitos desses objetos são apenas para trafegar dados dentro da aplicação. Eles não tem inteligência nenhuma, são como fantoches. Mas o que o JProfiler aponta é que o garbage collector está precisando fazer Full GC toda hora, e isso gasta tempo!
  • Muito uso de Reflection do java dentro de loops bastante grandes. Esse recurso é muito poderoso, mas deve-se tomar algumas precauções. O desempenho da aplicação é melhor quando a chamada de um método é feito da maneira convencional. Se for para dar produtividade e o overhead não for tão grande, vale a pena. Por outro lado o uso de reflection pode deixar o código difícil de entender. No caso da aplicação em análise uma solução mais Orientada a Objetos eliminaria esses impulsos por querer dificultar problemas que seriam simples. Só para uma curiosidade, o Reflection foi rescrito no java 1.4 para melhorias de performance.
  • Comparação de strings para buscar um objeto em uma lista. Essa busca de objetos pode ser otimizada pela própria linguagem utilizando, por exemplo, o método contains de um collection. Um loop utilizando Java.util.Vector pode ser transformado em um Java.util.HashSet para buscar o objeto mais rapidamente se no caso não importar a ordem dos objetos. Porém se a intenção for fazer cálculos com atributos de uma classe, como ocorre em algums pontos da aplicação, a idéia seria que a própria classe (entidade) faça o cálculo a partir de seus atributos. Isso, além de ser mais Orientado a Objetos, eliminaria a necessidade de fazer loops para buscar o objeto e setar um valor nele.
  • Loops desnecessários. Alguns loops podem ser eliminados apenas com uma solução mais orientada a objetos. Outros podem ser eliminados apenas alterando a consulta no banco de dados para já trazer um resultado calculado, por exemplo.
  • Problemas em aberturas e tempo de vida de transações de banco de dados. Esse com certeza é um dos piores mas não vale a pena eu comentar pois a solução depende de cada aplicação.
Aplicações em Ruby on Rails sofrem com a falta de thread safety, o que pode prejudicar a escalabilidade. Mais o pessoal está escalando uma grande aplicação em Rails fazendo um uso extensivo de cache de fragmentos. Que tal o GUJ rodar em Rails 7 vezes mais rápido do que roda em java? Segue o link do bate-papo.
Conclusão:

Tem muita gente dizendo que Ruby on Rails não escala por causa do case do twitter mas tá aí uma prova que mesmo uma aplicação em Java, com recursos como GC, JIT e hotspot pode não escalar, pois não é a linguagem que não escala, e sim o modelo que não foi pensado para escalar.

Fluent Interface

Fluent Interface é usada para deixar o código muito mais limpo, fácil de entender e dar manutenção. A idéia é que o código do domínio fique mais parecido com a forma que falamos, para um melhor entendimento do código. O objetivo é fazer uso de uma DSL Interna para se aproximar à linguagem natural, no nosso caso o Português!

Vou mostrar o exemplo de um código e refatorá-lo até que fique fluente. Trata-se de uma aplicação de transação bancária que será demonstrada em três fases.

Fase 1:

Imagem19

Quais são os problemas desse código? Vários! Ele funciona normalmente e vai trazer os resultados esperados, porém ele pode se tornar muito ruim para dar manutenção por não ser fluente. Vamos ver por quê?

A entidade Conta parece não ter inteligência nenhuma, pois ela não sabe debitar ou creditar um valor em seu saldo. Outro problema é que se o calculo do débito ou do crédito mudar, será necessário alterar todo lugar na aplicação que estiver usando esse cálculo pois ele não está centralizado na classe Conta. Esse código precisa de comentários pois ele não é auto-explicativo.

Um objeto deve, em termos de Orientação a Objetos, saber o porquê de sua existência e conhecer seus estados válidos. O objeto não deve fornecer métodos que invalidem seu estado. Nesse exemplo, uma classe cliente poderia esquecer um parênteses de deixar o saldo inválido:

conta.setSaldo(conta.getSaldo() + valor * 2 );

Não devemos pensar em uma classe como uma mera coleção de atributos. Objetos também não são atributos mais funções, e sim estado + comportamento. O Phillip Calçado explica muito bem isso!

Refatorando, o método ficaria assim:

Fase 2:

Imagem20

Um pouco melhor pois agora não precisa de comentários, já que a Conta sabe debitar e creditar. Porém esse código ainda tem muito ruído e pode se tornar mais legível.

Vou dar um exemplo de como ficaria a implementação do mesmo método usando fluent interface.
Fase 3:

Imagem21

O código fica bem mais limpo. A implementação dos outros métodos ficaria assim:

Imagem22

Nesse último exemplo utilizei o conceito de Repositório, o qual faz mais sentido no domínio do que os DAOs. A validação do valor do dinheiro no primeiro exemplo agora fica no construtor na classe dinheiro, o que faz mais sentido.

Imagem23

O Guilherme explicou muito bem no blog dele sobre o assunto nesses posts. Vale a pena dar uma espiadinha. 🙂
Publicado em design. Tags: , . 11 Comments »

Metodologia Ágil

Estava conversando sobre metodologias com um amigo, gerente de projeto da empresa o qual trabalho, e quando falei de Scrum ele se mostrou muito interessado no assunto. Porém fui surpreendido quando ele falou que conhecia outra metodologia, o famoso XP, e disse que se o Scrum for como o XP seria uma carta fora do baralho. Curioso em saber o porquê ele me disse que trabalhar em par é coisa de criança, e não tinha mais argumentos para falar sobre o XP. Então eu expliquei que tem o outro lado da moeda. Trabalhar em par possibilita a troca de conhecimentos da equipe e a codificação é revisada a todo momento. E para fazer críticas a uma metodologia temos que pelo menos entendê-la como um todo, e não por causa de uma ou duas regras dessa.

Muita gente ainda tem preconceito de metodologias ágeis pois acha que isso não vai pegar, mas por puro desconhecimento nem imagina que isso já pegou! No Brasil ainda não está muito difundido, mas acretido que o mercado está mudando. Grandes empresas já adotam essa metodologia, como por exemplo a Globo.com com alguns cases de sucesso. Mas por que estão adotando agilidade? Vejamos:

Os projetos atuais e tradicionais não estão tendo sucesso! Gantt Chart não funciona! Processos waterfall não funcionam! As fábricas de software não estão conseguindo cumprir os prazos porque esse modelo tem muitos problemas!

Esse gráfico é antigo, mas acredito que hoje ainda não esteja muito diferente. Ele mostra que apenas 16% tem sucesso e são entregues no prazo.

Muitos comparam a engenharia de informática com engenharia mecânica mas são engenharias completamente diferentes. Na informática a formula ( Progresso = Número de Pessoas / Número de Tarefas) não é verdade.

Um modelo em cascata, também conhecido como waterfall, tem o seguinte aspecto:

Já num modelo incremental essas fases devem ocorrer a todo tempo. Em curtos intervalos de tempo todas essas fases devem ser executadas e revisadas.

Muita gente diz que aplica RUP mas na verdade faz tudo waterfall. Passam meses fazendo páginas e mais páginas de documentação e entregam para desenvolvedores que precisam ler tudo, interpretar os textos e traduzir tudo em código. Sempre ocorre problemas de interpretação e geralmente nem tudo é lido antes de começar o desenvolvimento. Depois vem a frase conhecida do cliente “mas não era isso que eu queria”. Acontece que é difícil manter a documentação porque os requisitos mudam. As vezes o cliente descobre o que realmente queria depois que começa a usar o software, e o que mais vemos é trabalhos e re-trabalhos. Esses documentos, muitas vezes chamados de contrato, serão o alicerce de discussões entre clientes e prestadores. Vejam, eu não sou contra documentação e nenhuma das metodologias ágeis falam que não deve ter documentação! Documentação é importante, mas é mais importante o software funcionando do que o detalhamento de todos os escopos num documento. Melhor ainda se a documentação for executável para garantir que está refletida no código.

Por isso que surgiu as metodologias ágeis, por isso que surgiu o Scrum, por isso surgiu o Manifesto Ágil!

Comecei a utilizar técnicas do Scrum junto com técnicas de XP e obtive melhorias em meu trabalho rapidamente. Essas idéias ágeis formam um framework de processos que resolve a maioria dos problemas conhecidos, então por que não usar? Será que é muito difícil?

É claro que não é a certeza do sucesso, mas se a equipe for bem  qualificada e atenta, dificilmente ocorrerá desvios que possam prejudicar o andamento do projeto.

Demorou!

Demorou mais saiu! Dei uma pausa nas prioridades e agora vou dedicar tempo para o blog. Futuramente (a curto prazo, espero ) vou disponibilizar o blog em Inglês também. Espero que seja proveitoso para alguém 🙂

Publicado em Sem Categoria. Tags: . Leave a Comment »