Locawebers

[Joca] Restriction driven simplicity

20 de janeiro de 2012

I just returned from vacation and was reviewing some photos in my cel phone when I found some old photos from a previous trip to SF. In the airport there was an exhibition about TV sets and some old remote controls got my attention. Here’s a picture of them:

Old TV remote control

Old TV remote control

Checkout the number of buttons in the remote control. The maximum is 4. There are some remotes with only one button. When I was a kid I remember the first TV bought in my house with a remote control that had only 2 buttons, one for volume and other for changing channel. That simple! That was around 1975. At the time, the technology for making a remote control was too expansive, so it could not be too complicated and have too many buttons, otherwise it would be too expansive to be sold in the market. That was the restriction that drove the simplicity of those 1st generation remote control. Now we don’t have that restriction and we get remotes that can accomplish much more tasks but are way more complex. Take a look at the picture below (and I even picked a not-so-complex one!):

Digital TV Remote Control

Digital TV Remote Control

So maybe next time we want to design something more simple, we can think of imposing some restrictions to the design process! :-)

[Fernando Hamasaki de Amorim] [IT Web - Ruby Fundamental] Módulos com mixin

16 de janeiro de 2012

Em um post anterior do blog Ruby Fundamental vimos como usar módulos como namespaces. Agora veremos como usar os módulos em Ruby como mixin, misturando os métodos de instância de um módulo em outras classes.

Veja o post completo no blog Ruby Fundamental:
Módulos como mixin

Veja também os outros posts do blog Ruby Fundamental:


[Fernando Hamasaki de Amorim] 87ª Corrida Internacional de São Silvestre – 15 km

8 de janeiro de 2012

Para finalizar o ano de 2011, debaixo de muita chuva, no dia 31 de dezembro corri os 15 km da 87ª Corrida Internacional de São Silvestre.

Com a alteração do percurso, a largada foi na avenida Paulista, mas a chegada no Obelisco, em frente ao Parque do Ibirapuera.

Tempo total: 01:26:51

Tempo médio por km: 05:47

Tempo em cada km:

  1. 06:19
  2. 05:27
  3. 05:30
  4. 04:54
  5. 05:30
  6. 05:20
  7. 05:35
  8. 06:04
  9. 05:42
  10. 06:34
  11. 06:16
  12. 06:33
  13. 06:18
  14. 05:29
  15. 05:20

Foto de Treino Online

Foto de Treino Online

Foto de WebRun

Foto de WebRun

A medalha da São Silvestre é de muito boa qualidade

A medalha da São Silvestre é de muito boa qualidade


[Joca] Using checklists to deal with the unexpected

3 de janeiro de 2012

I mentioned earlier about “The Checklist Manifesto” book. The post was originally written in Portuguese but you can find a Google translation here. In this post I mentioned about the use of checklist in surgeries and other medical procedures and how we could use checklists in the IT environment.

I was reviewing my Kindle highlights for this book and found this highlight:

Surgery has, essentially, four big killers wherever it is done in the world: infection, bleeding, unsafe anesthesia, and what can only be called the unexpected. For the first three, science and experience have given us some straightforward and valuable preventive measures we think we consistently follow but don’t. These misses are simple failures — perfect for a classic checklist. And as a result, all the researchers’ checklists included precisely specified steps to catch them.

But the fourth killer — the unexpected — is an entirely different kind of failure, one that stems from the fundamentally complex risks entailed by opening up a person’s body and trying to tinker with it. Independently, each of the researchers seemed to have realized that no one checklist could anticipate all the pitfalls a team must guard against. So they had determined that the most promising thing to do was just to have people stop and talk through the case together — to be ready as a team to identify and address each patient’s unique, potentially critical dangers.

Dr. Gawande found out that in order to address the unexpected, checklists should not only include task checks but also communication checks. Dr. Gawande got to that conclusion visiting a 700,000-square-foot office and apartment complex construction site with between two to five hundred workers on-site on any give day managed by a man called Finn O’Sullivan. The volume of knowledge and degree of complexity O’Sullivan manages is impressive and it was as monstrous as anything Dr. Gawande had encountered in medicine. Here’s the explanation:

It was also a checklist, but it didn’t specify construction tasks; it specified communication tasks. For the way the project managers dealt with the unexpected and the uncertain was by making sure the experts spoke to one another — on X date regarding Y process. The experts could make their individual judgments, but they had to do so as part of a team that took one another’s concerns into account, discussed unplanned developments, and agreed on the way forward. While no one could anticipate all the problems, they could foresee where and when they might occur. The checklist therefore detailed who had to talk to whom, by which date, and about what aspect of construction — who had to share (or “submit”) particular kinds of information before the next steps could proceed.

The submittal schedule specified, for instance, that by the end of the month the contractors, installers, and elevator engineers had to review the condition of the elevator cars traveling up to the tenth floor. The elevator cars were factory constructed and tested. They were installed by experts. But it was not assumed that they would work perfectly. Quite the opposite. The assumption was that anything could go wrong, anything could get missed. What? Who knows? That’s the nature of complexity. But it was also assumed that, if you got the right people together and had them take a moment to talk things over as a team rather than as individuals, serious problems could be identified and averted.

So next time you design a checklist, remember to include not only task checks but also communication checks.

[Nando Vieira] Ruby e o duck typing

2 de janeiro de 2012

No Ruby, nós não declaramos o tipo de objetos, nem o tipo do retorno de métodos. Embora isso possa parecer algo muito ruim para quem está acostumado com linguagens como Java, linguagens dinamicamente tipadas como o Ruby são muito flexíveis, produtivas e, acredite, seguras. Na maioria das vezes, o medo de não poder contar com o compilador para fazer verificações de tipos não tem fundamento.

Desenvolvedores Ruby estão mais acostumados em definir objetos pelo que eles podem fazer, do que por seu tipo. Esta técnica é chamada de duck typing.

Se anda como um pato e faz barulho como um pato, então deve ser um pato. E o interpretador ficará feliz em fazer com que o objeto seja tratado como um pato. Na prática, isso significa que em vez de fazer verificações de tipo de um objeto, você deve se preocupar se este objeto é capaz de executar o método que você precisa.

Pegue como exemplo strings, arquivos e arrays. As classes Array, File e String implementam o método de instância <<, que quase sempre significa append. Você pode se aproveitar desta interface para criar, por exemplo, uma classe de log que não se importa com o tipo de objeto que irá armazenar esses logs.

class SimpleLogger
  def initialize(io)
    @io = io
  end
 
  def log(message)
    @io << "#{Time.now} - #{message}\n"
  end
end

A classe SimpleLogger consegue enviar os logs para arrays, strings, arquivos e, se quiser, para qualquer outro objeto que implemente o método <<.

O Ruby realmente abraça o duck typing por toda a linguagem. Diversos protocolos exigem que o objeto apenas implemente um método to_<protocol>. Muitas operações que envolvem arrays, por exemplo, exigem que o objeto do lado direito da expressão apenas implemente o método to_ary.

class Numbers
  def to_ary
    [4, 5, 6]
  end
end
 
[1, 2, 3] + Numbers.new
#=> [1, 2, 3, 4, 5, 6]

A classe Hash, por exemplo, permite que você una dois objetos, desde que o método to_hash seja implementado.

class Configuration
  def to_hash
    {root: "/etc"}
  end
end
 
config = Configuration.new
 
{name: "Custom config"}.merge(config)
#=> {:name=>"Custom config", :root=>"/etc"}

Não é preciso dizer que este tipo de protocolo por convenção permite criar códigos muito mais flexíveis, com extrema facilidade.

Isso não significa que saber o tipo de objetos não seja útil. Veja, por exemplo, as operações matemáticas. Qualquer objeto pode ser convertido em números. Para isso, basta implementar o método coerce, que recebe o objeto que está solicitando a coerção. O exemplo abaixo mostra como criar uma classe cuja instância pode ser convertida em números inteiros e flutuantes, mas não em instâncias da classe BigDecimal.

class NumberOne
  def coerce(object)
    case object
    when Integer
      [object, 1]
    when Float
      [object, 1.0]
    else
      raise TypeError, "#{self.inspect} can't be coerced into #{object.class}"
    end
  end
end
 
puts 1 + NumberOne.new
#=> 2
 
puts 1.0 + NumberOne.new
#=> 2.0
 
require "bigdecimal"
puts BigDecimal.new("1.0") + NumberOne.new
#=> TypeError: FakeNumber can't be coerced into BigDecimal

O duck typing vai além de simples regras; é um estilo de programação. Antes de exigir tipos de objetos, pergunte-se se isso é realmente necessário. Às vezes, o tipo do objeto é muito importante, mas muitas vezes isso simplesmente não importa.

NOTA: Este artigo foi tirado do e-book "Conhecendo o Ruby" que estou escrevendo. Se inscreva na newsletter do HOWTO e saiba quando ele for lançado.

[Fernando Hamasaki de Amorim] Feliz 2012!

1 de janeiro de 2012

2012

Desejo um 2012 com muito amor, paz, felicidade, saúde, respeito e dignidade.

E menos egoísmo, cigarros, falta de ética, mentiras e aproveitamento de situações para se levar vantagem sobre os outros de forma desonesta.

Feliz ano novo!


[Nando Vieira] Hospendando sites estáticos no Heroku

28 de dezembro de 2011

Faz algum tempo que venho usando o plano gratuito do Heroku para hospedar páginas estáticas, embora você consiga ir muito além disso. De qualquer modo, é uma maneira muito prática de ter sites estáticos com o poder do deploy de aplicações através de um simples push do Git.

O processo em si é bastante simples. Primeiro, você deve organizar todos os seus arquivos em algum diretório, por exemplo, some_site/public. Este diretório pode conter arquivos HTML, JavaScript e CSS. Na prática, você pode servir qualquer tipo de arquivo.

Crie o arquivo some_site/config.ru. Nós iremos servir os arquivos estáticos com Rack. Primeiro, nós vamos criar um aplicativo usando o Rack::Builder. Este aplicativo usará um middleware que redirecionará a requisição na raíz do site para o arquivo some_site/public/index.html.

Todos os outros arquivos do diretório some_site/public serão servidos com o Rack::Directory.

app = Rack::Builder.new do
  use Rack::Static, urls: {"/" => "index.html"}, root: "public"
  run Rack::URLMap.new({
    "/" => Rack::Directory.new("public")
  })
end
 
run app

Crie também um arquivo Gemfile, que terá como única dependência o próprio Rack. Este arquivo Gemfile deve estar na raíz do seu projeto e será algo como isto.

source :rubygems
gem "rack", "~> 1.3"

Execute o comando bundle install para instalar a dependência e gerar o arquivo Gemfile.lock.

Na raíz do projeto, inicie um novo repositório Git e faça o commit inicial.

$ cd some_site
$ git init
Initialized empty Git repository in /Users/fnando/Sites/some_site/.git/
$ git add .
$ git ci -am "Initial commit"
[master (root-commit) 54e37c9] Initial commit
 4 files changed, 31 insertions(+), 0 deletions(-)
 create mode 100644 Gemfile
 create mode 100644 Gemfile.lock
 create mode 100644 config.ru
 create mode 100644 public/index.html

Agora, basta criar seu aplicativo no Heroku. Se você ainda não possui uma conta configurada, veja o que é preciso fazer. Se tudo estiver certo, você pode criar um novo aplicativo com o comando heroku apps:create <seu-app>. O stack padrão é baseado no Ruby 1.9, então estamos muito bem acompanhados.

$ heroku apps:create some-site
Creating some-site... done, stack is bamboo-mri-1.9.2
http://some-site.heroku.com/ | git@heroku.com:some-site.git
Git remote heroku added

Para fazer o deploy, execute o comando git push heroku.

$ git push heroku 
Counting objects: 7, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (7/7), 768 bytes, done.
Total 7 (delta 0), reused 0 (delta 0)
 
-----> Heroku receiving push
-----> Ruby/Rack app detected
-----> Gemfile detected, running Bundler version 1.0.7
       Unresolved dependencies detected; Installing...
       Using --without development:test
       Fetching source index for http://rubygems.org/
       Installing rack (1.3.5) 
       Using bundler (1.0.7) 
       Your bundle is complete! It was installed into ./.bundle/gems/
-----> Compiled slug size is 152K
-----> Launching... done, v3
       http://some-site.heroku.com deployed to Heroku
 
To git@heroku.com:some-site.git
 * [new branch]      HEAD -> master

Certifique-se que está tudo funcionando. Basta acessar a URL exibida após o deploy que, neste caso, é http://some-site.heroku.com.

Obviamente, usar esta URL não é nada profissional. Você pode configurar seu próprio domínio, sem gastar nada (se não me engano, você precisa adicionar o seu cartão de crédito, mesmo sendo funcionalidades gratuitas). Adicione a extensão "Custom Domains".

$ heroku addons:add custom_domains:basic
-----> Adding custom_domains:basic to some-site... done, (free)

Adicione também a extensão "Zerigo DNS".

$ heroku addons:add zerigo_dns:basic
-----> Adding zerigo_dns:basic to some-site... done, (free)

Finalmente, você pode adicionar seu domínio com o comando heroku domains:add <seu domínio>.

$ heroku domains:add somesite.com
Added somesite.com as a custom domain name for some-site

Você precisará adicionar o registro de DNS que irá redirecionar www.somesite.com para somesite.com no site da Zerigo. Para acessar este painel de controle, execute o comando heroku addons:open zerigo_dns:basic.

$ heroku addons:open zerigo_dns:basic
Opening zerigo_dns:basic for some-site...

Clique no botão "Configure".

Painel do Zerigo DNS no Heroku

Você será redirecionado para uma tela como esta:

Zerigo DNS

Clique no link "Host > Add" para adicionar um novo registro. No campo "Host", digite "www", defina o tipo do registro como sendo "Redirect" e, por último, digite a URL de destino no campo "Data".

Zerigo DNS - Adicionando redirecionamento

O Zerigo DNS funciona bem para poucos acessos, mas você pode rapidamente ultrapassar o limite do plano básico. Neste caso, sugiro que dê uma olhada no serviço oferecido pela DNSimple, que custa apenas US$3 para 10 domínios e é extremamente simples de configurar; existe até uma opção de configuração com apenas um clique para aplicativos hospedados no Heroku.

[Marcelo Leal] A Pleasant Surprise!

21 de dezembro de 2011
I would like to say that i’m used to the kind of things i will tell you in this post, but the “sad” reality is that i’m not. Two good surprises at the end of this 2011 year, and two good gifts for the christmas. Last time i did visit US this year, i did [...]


[Nando Vieira] Usando presenters no Rails

18 de dezembro de 2011

Um problema muito recorrente de aplicativos de médio-grande porte é que as views são uma bagunça.

É muito comum termos condições em nossas views. Objetos possuem diferentes estados e muitas vezes precisamos mostrar esses estados visualmente. E normalmente começamos pelo caminho mais fácil, que é adicionar ifs na view.

Acontece que isso não precisa ser sempre assim. Neste artigo vou mostrar como funciona um pattern chamado Presenter, que permite diminuir/remover a complexidade de views e controllers.

Começando com o seu próprio presenter

A primeira coisa que você precisa detectar é que tipo de lógica é possível extrair de sua view. Algumas coisas mais genéricas fazem mais sentido serem extraídas como helpers. Outras, como ifs para determinar qual partial deve ser renderizada provavelmente devem ser movidas para seu presenter.

Imagine que você tenha uma view como esta:

<h1><%= @product.name %></h1>
 
<% if @product.description %>
  <p class="description"><%= @product.more %></p>
<% end %>

Não se deixe enganar por esse tipo de lógica. Embora pareça inofensiva, coisas como esta podem sair do controle rapidamente.

Esta view precisa de uma variável @product que deve ser definida em nosso controller:

class ProductsController < ApplicationController
  def show
    @product = Product.find(params[:id])
  end
end

Agora, precisamos de uma classe que irá "envelopar" nossa instância da classe Product. Crie o arquivo app/presenters/product_presenter.rb. Como este diretório não está no load path do Rails, vamos ter que fazer uma configuração no arquivo config/application.rb.

module HOWTO
  class Application < Rails::Application
    # ... 
    config.autoload_paths << config.root.join("app/presenters").to_s
  end
end

Volte ao arquivo product_presenter.rb e crie a classe ProductPresenter.

class ProductPresenter
  def initialize(product)
    @product = product
  end
end

Esta classe será responsável por expor todos os atributos que nossa view irá acessar. Em vez de definir cada um dos métodos manualmente, podemos apenas delegar as chamadas para o objeto. Para fazer isso, vamos usar o método Module#delegate, adicionado pelo ActiveSupport.

class ProductPresenter
  delegate :name, :description, to: :"@product"
 
  def initialize(product)
    @product = product
  end
end

Qualquer chamada aos métodos ProductPresenter#name e ProductPresenter#description serão delegadas para o objeto que foi armazenado em @product. Você também poderia utilizar o módulo Forwardable, mas a versão adicionada pelo ActiveSupport é mais elegante.

Agora, podemos remover aquele if. Se você não se lembra mais dele, dê uma última olhadela, pois logo ele não mais existirá! Adicione o método description. Faça com que este método retorne o parágrafo com a descrição, caso ela tenha sido definida. Como é necessário retornar uma tag HTML, vamos usar o helper content_tag.

class ProductPresenter
  delegate :name, to: :"@product"
 
  def initialize(product)
    @product = product
  end
 
  def description
    if @product.description.present?
      helpers.content_tag(:p, @product.description, class: "description")
    end
  end
 
  private
  def helpers
    ApplicationController.helpers
  end
end

Altere o controller para que ele passe a instância da classe Product para o presenter.

class ProductsController < ApplicationController
  def show
    @product = ProductPresenter.new(Product.find(params[:id]))
  end
end

Para finalizar, basta modificar nossa view.

<h1><%= @product.name %></h1>
<%= @product.description %>

Para o caso de partials, o funcionamento é basicamente o mesmo. No entanto, em vez de fazer a renderização no próprio presenter, é mais fácil retornar o nome da partial que deve ser renderizada.

Imagine que nossa view tenha mais um if que irá renderizar uma partial diferente para produtos gratuitos.

<% if @product.paid? %>
  <%= render "order", product: @product %>
<% else %>
  <%= render "download", product: @product %>
<% end %>

Podemos implementar um método chamado ProductPresenter#checkout_partial que irá fazer aquele if, retornando apenas o nome da partial.

class ProductPresenter
  delegate :name, to: :"@product"
 
  def initialize(product)
    @product = product
  end
 
  def description
    if @product.description.present?
      helpers.content_tag(:p, @product.description, class: "description")
    end
  end
 
  def checkout_partial
    @product.paid? ? "order" : "download"
  end
 
  private
  def helpers
    ApplicationController.helpers
  end
end

E na nossa view, basta renderizar o retorno do método ProductPresenter#checkout_partial.

<%= render @product.checkout_partial, product: @product %>

A esta altura, você já deve ter percebido como presenters podem remover completamente a lógica das views. Embora seja muito fácil fazer isso sem a necessidade de bibliotecas, algumas coisas precisam ser implementadas toda vez. É o caso de helpers, rotas e métodos de internacionalização.

Pensando nisso, decidi extrair aquela organização de código que eu estava utilizando em uma gem chamada simple_presenter.

Usando o simple_presenter

Para instalar, basta executar o comando abaixo:

$ gem install simple_presenter

Lembre-se de adicionar a gem ao arquivo Gemfile.

source :rubygems
gem "rails", "3.1.3"
gem "simple_presenter", "~> 0.1"

Aquele mesmo presenter que definimos pode ser trocado por algo como isto:

class ProductPresenter < Presenter
  expose :name, :description
 
  def description
    if @subject.description.present?
      h.content_tag(:p, @subject.description, class: "description")
    end
  end
 
  def checkout_partial
    @subject.paid? ? "order" : "download"
  end
end

Note que não precisamos mais definir o método ProductPresenter#initialize, nem o método ProductPresenter#helpers. Também tivemos que mudar todas as referências a @product para @subject; isso é necessário porque, por padrão, o nome do objeto que receberá os métodos delegados é @subject.

O simple_presenter adiciona os métodos helpers e h que permite acessar os helpers do Rails. Os helpers de rotas podem ser acessados com os métodos routes e r. E, finalmente, os helpers de internacionalização podem ser acessados por translate e t, e localize e l.

Escrevendo testes

Escrever testes para presenters é muito simples. No caso do RSpec, basta criar o diretório spec/presenters. Aquele nosso presenter pode ter testes como este:

require "spec_helper"
 
describe ProductPresenter do
  let(:product) { mock(Product, name: "Some product") }
  subject { described_class.new(product) }
 
  its(:name) { should eql("Some product") }
 
  describe "#description" do
    it "returns content" do
      product.stub description: "Some description"
      expected = %[<p class="description">Some description</p>]
 
      subject.description.should eql(expected)
    end
 
    it "returns no message" do
        subject.description.should be_blank
    end
  end
 
  describe "#checkout_partial" do
    it "returns partial for paid products" do
      product.stub paid?: true
      subject.checkout_partial.should eql("order")
    end
 
    it "returns partial for free products" do
      product.stub paid?: false
      subject.checkout_partial.should eql("download")
    end
  end
end

Finalizando

Você deve ter percebido que presenters permitem tornar suas views muito mais simples. Além disso, eles tem a vantagem de serem fáceis de testar.

A coisa mais difícil dos presenters é se acostumar com eles. Mas depois que você se acostuma, dificilmente terá uma view complicada e também nem vai querer deixar de usá-los!

UPDATE 1: O Valim me lembrou que à partir do Rails 3 não é mais preciso adicionar diretórios app/*, pois o Rails faz isso automaticamente. Eu sabia disso, mas o costume ainda permanece.

[dovb] Treinamento sobre Innovation Games (/cc @adaptworks)

13 de dezembro de 2011

 

Na semana passada tive a oportunidade de participar do treinamento de Innovation Games, promovido pela Adaptworks, com Michael Gaines.

Os “jogos de inovação” são alguns jogos elaborados por uma consultoria do Vale do Silício, The Innovation Games Company ®, criada pelo canadense Luke Hohmann, que cria jogos que estimulam o engajamento de clientes, colegas e parceiros no desenvolvimento de produtos/projetos.

Por sua informalidade, a técnica de jogos permite que pessoas de diferentes níveis hierárquicos, com diferentes papéis na empresa no ou na equipe de desenvolvimento de produto/projeto, sintam-se a vontade para expor suas visões sobre o que está sendo feito.

No treinamento nos fizemos alguns dos jogos, que nos ajudaram a aplicar diferentes técnicas para priorizar atividades no desenvolvimento de um projeto/produto, a entender melhor aspectos que estimulam ou atrasam o ciclo de desenvolvimento e a relacionar recursos existens a fim de se chegar a novas idéias através da associação destes recursos.

Aqui vai uma breve descrição dos jogos que praticamos:

- Speed Boat – ajuda a entender o que seus clientes gostam ou não gostam em seu produto ou serviço, quais são os aspectos que estão ajudando a acelerar ou a desacelerar seu projeto ou ainda a entender quais são os fatores de motivação e desmotivação que sua equipe percebe no projeto. A técnica garante que reuniões de retrospectiva / avaliação fiquem sob controle e não se transformem numa avalanche de reclamações em que só aparecem os aspectos negativos do projeto, sem se pensar em como resolvê-los e avançar. A técnica é bem simples, você precisa apenas desenhar um barco num quadro branco ou folha de papel pendurada na parede, e as pessoas devem marcar, com post-its, as coisas que “ancoram” o barco, e as coisas que o fazem andar com maior velocidade. Os itens podem ter peso (marcado nos post-its), ou simplesmente estar em posições diferentes no quadro (as coisas que mais atrapalham ficam mais fundas, como se fossem as âncoras mais pesadas).

- Buy a Feature – ajuda a fazer com que seu cliente (ou CEO, ou Diretor, ou Gerente de Produtos, etc) consiga priorizar melhor o desenvolvimento de features que realmente irão agregar mais valor ao negócio. Geralmente o cliente quer o projeto todo pronto, para ontem. Mas nem todas as features serão usadas, nem todas são críticas para o lançamento e nem todas precisam de fato ser feitas (isso vai acabar sendo descoberto com o uso do produto). O jogo consiste em ter uma lista de features, e a dar um preço para cada uma delas (na vida real, o preço pode ser a estimativa e o custo de desenvolvimento, por exemplo). Cada cliente receberá um certo valor para poder comprar as features, mas, obviamente, não terá dinheiro suficiente para todas. Portanto, para algumas features, ele terá que negociar com outros clientes para que os dois juntos tenham recursos suficientes para comprá-las, e terá que abrir mão de outras. O resultado deste jogo é que o conjunto de clientes de seu produto terá priorizado o que realmente lhes traz valor.

- Remember the Future – o que você precisa fazer em seu produto para que daqui a 1 ano ele tenha trazido determinado benefício ao seu cliente? Partindo do benefício, a idéia deste jogo é pensar de traz para frente o que é necessário fazer com o produto para que ele traga tal benefício, e o que precisou ser feito imediatamente antes para que ele chegasse até este ponto. Dado o prazo para o produto atingir o objetivo, este jogo faz com que as pessoas pensem no que é realmente necessário para partir do ponto em que se está hoje, para se chegar ao ponto em que o produto trará o benefício esperado.

- Prune the Product Tree – todas as features são importantes e precisam ser entregues ao mesmo tempo? Isso não é verdade, e com este jogo você e sua equipe poderão montar o roadmap de seu produto pensando nos diversos aspectos do produto. A metodologia consiste em desenhar uma árvore, e ir colocando, com post-its, para dar o formato desejado à copa da árvore. Assim, os galhos da árvore representam os tipos de funcionalidade, as funcionalidades em si são as folhas, as features fundamentais são o tronco, e a base da aplicação são as raízes. Assim, as pessoas vão colando as folhas nos devidos galhos, sendo que as funcionalidades já prontas ou mais desejáveis ficam mais perto do tronco do que as menos importantes. A metologia deixa vísivel quando, por exemplo, algum aspecto de seu produto está ficando de lado (ex: muitas folhas no ramo que diz respeito ao front-end de sua plataforma de comércio eletrônico e poucas no raml que diz respeito ao back-end), para que você possa avaliar se está é mesmo a melhor opção.

- Product Box – Desenhando a caixa que venderia seu produto ou serviço num supermercado, os jogadores terão que identificar quais os aspectos mais importantes do produto, como comunicá-los melhor e quais problemas de fato seu produto resolve. As limitações de espaço exigirão que o grupo pense no que realmente são as principais características do produto, e tenha criatividade para comunicar da melhor forma.

- Spider Web – Este jogo, que funciona através do desenho de uma rede que relacione todos os produtos, serviços ou usos que podem ser feitos com seu produto na forma de uma teia de aranha. Com isso, percebe-se novos usos que podem ser feitos do produto através das conexões que aparecerão.

- Start Your Day – Descreva como seu cliente usa ou se relaciona com seu produto ao longo do tempo (pode ser um dia, uma semana, um mês ou qualque período, depende do seu produto). Pense em todas as situações em que seu produto é necessário para o cliente, e como seu produto pode ajudá-lo em cada caso. Com isso você entenderá melhor como seu produto é usado, para quais aspectos você tem que dar mais importância, e obviamente, ajudará a pensar na experiência do usuário, sob todos os aspectos.

Sempre que possível envolva também o cliente, afinal, é importante ele estar engajado com o projeto e totalmente alinhado com sua equipe.

Estes e outros jogos criados pela The Innovation Games Company (R) estão disponíveis no livro Innovation Games: Creating Breakthrough Products Through Collaborative Play, que todos os participantes do treinamento receberam como cortesia.

Pará vários dos jogos há versões onlines, para que times remotos possam participar, mas obviamente o ideal é a equipe estar toda reunida, uma vez que a colaboração e o debate são fundamentais para que os resultados esperados sejam alcançados.

Se você já aplicou alguma destas técnicas em alguma empresa ou cliente, aproveite o espaço de comentários do blog para contar sua experiência!

Se não aplicou, lembre-se, a técnica de jogos é simples, mas exige uma preparação prévia da sala e dos materiais a serem utilizados para que funcione bem e envolva a equipe de jogadores!