Surgiu uma discussão na UML-BR sobre como modelar um Jogo da Memória. O rumo da conversa foi sobre pensar nas classes e modelar antes, influenciados por um post anterior. A thread sobre o jogo da memória está aqui:
http://br.groups.yahoo.com/group/UML-BR/message/9936
Eu comecei a pensar nesse problema e até pretendí mandar um diagrama de classe demonstrando uma provável solução, porém, este “mini” sistema é muito mais direcionado a comportamento do que a classes propriamente dito.
Atualmente tenho estudado bastante Ruby. Concordo com o Rodrigo Kumpera quando ele diz que Java “educou a grande massa sobre bom desenvolvimento OO” mas “cheira naftalina”. A linguagem continua em evolução, porém, algumas coisas no Java me irritam muito. A maior delas é o turnaround imenso. Volta e meia precisamos reiniciar o servidor. No Ruby as coisas são mais fáceis. A comunidade Ruby faz as coisas serem mais fáceis. Para resolver o problema do Jogo da Memória quis usar o RSpec. Para instalá-lo bastou:
gem install rspec
No Java já me imaginaria instalando uns 20 jars irritantes.
Voltando ao assunto “Jogo da Memoria” iniciei esse desenvolvimento pensando: “O que é necessário para jogar?” Por sorte sou pai de 2 filhas pequenas e tinha um Jogo do Mico aqui. Não é exatamente um Jogo da Memória mas serve pois são cartas aos pares. Com as cartas na mão me lembrei do nosso amigo Kent Beck e a “Spike Solution”: “Eu não preciso de 15 pares para testar o Jogo da Memória. Eu só preciso de 2 pares para ter uma solução plausível que diz que minha aplicação funciona.”
[photopress:DSC00110.JPG,full,pp_image]
Uma mesa, um jogador e dois pares de cartas: Tudo que é necessário para um Jogo da Memória completo.
Com essa metáfora e esses “elementos” na mão o próximo passo seria como montar a “partida” focado em comportamento. Pensei no meu próprio comportamento quando montei esse cenário para a foto.
[photopress:comportamento1.GIF,full,pp_image]
Este seria o comportamento esperado do jogo logo ao iniciar. Pense no objetivo do jogo. Nós queremos ganhar certo? Logo no ínicio nós precisamos ter um parâmetro palpável para saber se ganhamos ou não. Logicamente no ínicio do jogo ele não está ganho. A implementação desses comportamentos nesse momento está listada abaixo:
[photopress:implementacao1.GIF,full,pp_image]
A prática do BDD é extremamente próxima do TDD. BDD não é nada novo. É apenas uma visão unificada de TDD e DDD fornecendo uma Ubiquitous Language para essa abordagem de desenvolvimento.
OK. Neste momento temos um Jogo montado. Um aspecto importante para este jogo é saber comparar cartas. Vamos adicionar este requisito como comportamento.
[photopress:comportamento2.GIF,full,pp_image]
Vamos agora implementar isso na classe Carta.
[photopress:implementacao2.GIF,full,pp_image]
Cada vez que faço um passo desses eu tenho requisitos (comportamentos) e implementações em paralelo. Minha especificação (jogo_memoria_spec.rb) vai direcionando o desenvolvimento da minha aplicação (jogo_memoria.rb). Cada passo é mensurável e pode ser avaliado como válido. Além disso, minha aplicação possui as características de um design emergente. Dados e comportamentos só são adicionados quando realmente há embasamento em requisitos.
Com a capacidade de saber quando cartas são iguais, o próximo passo seria poder “virar” uma carta e em seguida virar outra carta que não seja par com a primeira. É um critério de falha com relação ao objetivo de ganhar o jogo. O comportamento e a implementação do comportamento estão abaixo:
[photopress:comportamento3.GIF,full,pp_image]
[photopress:implementacao3.GIF,full,pp_image]
Vamos agora definir o comportamento e a implementação para o sucesso de virar duas cartas encontrando o par:
[photopress:comportamento4.GIF,full,pp_image]
Com esses últimos comportamentos seria possível avaliarmos a nossa implementação do Jogo da Memória com 4 cartas. Para efetuar o download da aplicação completa acesse os links abaixo:
jogo_memoria_spec.rb
jogo_memoria.rb
O que eu tenho gostado muito em aplicar técnicas de TDD é ter requisitos executáveis. O BDD só nos traz mais ferramentas conceituais. O BDD tem foco no próprio comportamento e não em testes dos comportamentos. A evolução de ferramentas como o próprio RSpec poderá nos trazer a um mundo novo onde nunca mais teremos documentos de requisitos desatualizados.
Cada dia que passa a especialização e a divisão do trabalho fazem menos sentido no desenvolvimento de software.
(amigos rubistas: não sejam muito rigorosos com meu código, estou aprendendo ainda)