<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>*batteries not included</title>
	<atom:link href="http://blog.danielfmartins.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.danielfmartins.com</link>
	<description>Software development nonsenseness</description>
	<pubDate>Wed, 01 Oct 2008 00:45:08 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.2</generator>
	<language>en</language>
			<item>
		<title>Mudança de rumo</title>
		<link>http://blog.danielfmartins.com/2008/09/25/mudanca-de-rumo/</link>
		<comments>http://blog.danielfmartins.com/2008/09/25/mudanca-de-rumo/#comments</comments>
		<pubDate>Thu, 25 Sep 2008 03:08:38 +0000</pubDate>
		<dc:creator>Daniel F. Martins</dc:creator>
		
		<category><![CDATA[off-topic]]></category>

		<category><![CDATA[destaquenet]]></category>

		<category><![CDATA[empresa]]></category>

		<category><![CDATA[mudanças]]></category>

		<category><![CDATA[notícia]]></category>

		<guid isPermaLink="false">http://blog.danielfmartins.com/?p=345</guid>
		<description><![CDATA[Que fique claro: aqui é realmente o Daniel quem vos escreve. Sim, eu não morri. Pelo menos não ainda.  
Estou reiterando isso pois, a julgar pela frequência com que eu atualizo este blog ou jogo conversa fora com os amigos no MSN GTalk, não é de se duvidar que alguém pense que eu fui [...]]]></description>
			<content:encoded><![CDATA[<p>Que fique claro: aqui é realmente o Daniel quem vos escreve. Sim, eu não morri. Pelo menos não ainda. <img src='http://blog.danielfmartins.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Estou reiterando isso pois, a julgar pela frequência com que eu atualizo este blog ou jogo conversa fora com os amigos no <del>MSN</del> GTalk, não é de se duvidar que alguém pense que eu fui dessa para melhor. Mas enfim, eu estou escrevendo este <em>post</em> para dar duas notícias importantes.</p>
<p>A primeira notícia é boa: a partir de hoje, quando eu abrir um crediário e me perguntarem a minha profissão, eu posso dizer que sou <strong>empresário</strong>. Chique, né? A empresa, batizada de Destaquenet, foi aberta em Julho e a <a href="http://www.destaquenet.com/" onclick="javascript:urchinTracker ('/outbound/article/www.destaquenet.com');">versão inicial do site</a> já está no ar. E antes que me perguntem, o site foi feito em <a href="http://djangoproject.org/" onclick="javascript:urchinTracker ('/outbound/article/djangoproject.org');">Django</a>!</p>
<p>Mas voltando ao assunto, isso aconteceu por vários motivos. Um desses motivos &#8212; talvez o principal deles &#8212; foi para evitar problemas com o temido Leão do imposto de renda, afinal já faz um tempinho que eu venho trabalhando como <em>freelancer</em>. O outro motivo é que, apesar de eu estar bem servido de trabalho pelo menos até o ano que vem, a idéia é justamente não depender de apenas uma ou duas empresas, então é uma boa já deixar a casa arrumada para que eu possa prestar serviços para outras empresas também.</p>
<p>A outra notícia &#8212; que é boa <strong>e</strong> ruim &#8212; é que, além de todo o trampo que eu já fazia, agora eu tenho uma empresa para tocar, o que por si só já dá um trabalhão. Por isso, eu optei por descontinuar este <em>blog</em>. Se tiver algum <em>post</em> aqui que vocês achem interessante, me avisem para que eu o coloque no <a href="http://weblog.destaquenet.com/" onclick="javascript:urchinTracker ('/outbound/article/weblog.destaquenet.com');">blog da Destaquenet</a>.</p>
<p>Provavelmente este será o último <em>post</em> neste <em>blog</em>, por isso, se tem alguém que (ainda) se interessa pelo que eu escrevo, eu recomendo que assinem o <a href="http://weblog.destaquenet.com/feed/" onclick="javascript:urchinTracker ('/outbound/article/weblog.destaquenet.com');">feed</a> do <em>blog</em> da Destaquenet. Os <em>posts</em> no novo <em>blog</em>  deverão ter o mesmo teor dos que aqui se encontram; a diferença é que tentarei manter uma certa regularidade nas postagens, coisa que não vem acontecendo por aqui a um bom tempo.</p>
<p>Mas é isso aí então, conto com a compreensão de vocês e espero reencontrá-los na <a href="http://weblog.destaquenet.com/" onclick="javascript:urchinTracker ('/outbound/article/weblog.destaquenet.com');">minha nova casa</a>.</p>
<p>Grande abraço a todos!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.danielfmartins.com/2008/09/25/mudanca-de-rumo/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Depurando uma aplicação JavaEE no Glassfish</title>
		<link>http://blog.danielfmartins.com/2008/06/10/depurando-uma-aplicacao-javaee-no-glassfish/</link>
		<comments>http://blog.danielfmartins.com/2008/06/10/depurando-uma-aplicacao-javaee-no-glassfish/#comments</comments>
		<pubDate>Tue, 10 Jun 2008 16:41:06 +0000</pubDate>
		<dc:creator>Daniel F. Martins</dc:creator>
		
		<category><![CDATA[programação]]></category>

		<category><![CDATA[debugging]]></category>

		<category><![CDATA[dicas]]></category>

		<category><![CDATA[glassfish]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[javaee]]></category>

		<category><![CDATA[netbeans]]></category>

		<category><![CDATA[pt-br]]></category>

		<guid isPermaLink="false">http://blog.danielfmartins.com/?p=338</guid>
		<description><![CDATA[Este post, na verdade, é uma dica rápida para quem possui aplicações JavaEE rodando em servidores Glassfish e está tendo dificuldades na hora de rastrear a origem de possíveis bugs no código.
Habilitando o modo de debug
Existem duas maneiras de se habilitar o modo de debug no Glassfish: através do painel de administração ou durante a [...]]]></description>
			<content:encoded><![CDATA[<p>Este <em>post</em>, na verdade, é uma dica rápida para quem possui aplicações <a href="http://java.sun.com/javaee/" onclick="javascript:urchinTracker ('/outbound/article/java.sun.com');">JavaEE</a> rodando em servidores <a href="http://glassfish.dev.java.net/" onclick="javascript:urchinTracker ('/outbound/article/glassfish.dev.java.net');">Glassfish</a> e está tendo dificuldades na hora de rastrear a origem de possíveis <em>bugs</em> no código.</p>
<h3>Habilitando o modo de debug</h3>
<p>Existem duas maneiras de se habilitar o modo de <em>debug</em> no Glassfish: através do painel de administração ou durante a inicialização do domínio.</p>
<p>Para habilitar o modo de <em>debug</em> por padrão, através do painel de administração, basta marcar o campo <em>Debug</em> na tela <em>JVM Settings</em> e clicar em <em>Save</em>:</p>
<p><a href='http://blog.danielfmartins.com/wp-content/uploads/2008/06/debug_mode.png'><img src="http://blog.danielfmartins.com/wp-content/uploads/2008/06/debug_mode-150x150.png" alt="Debug mode" title="Glassfish Debug Mode" width="150" height="150" class="alignnone size-thumbnail wp-image-341" /></a></p>
<p>Basta reiniciar o domínio para ver que o servidor abre a porta <code>9009</code>, através da qual podemos conectar um <em>debugger</em>:</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">daniel@daniel-laptop:~/Appservers/Glassfish/bin$ asadmin start-domain domain1</div>
</li>
<li class="li1">
<div class="de1">Starting Domain domain1, please <span class="kw3">wait</span>.</div>
</li>
<li class="li1">
<div class="de1">Log redirected to &#8230;/server.log.</div>
</li>
<li class="li2">
<div class="de2">Redirecting output to &#8230;/server.log</div>
</li>
<li class="li1">
<div class="de1">Listening <span class="kw1">for</span> transport dt_socket at address: <span class="nu0">9009</span></div>
</li>
<li class="li1">
<div class="de1">Application server is listening at address <span class="nu0">9009</span> <span class="kw1">for</span> debugger to attach using transport dt_socket</div>
</li>
<li class="li1">
<div class="de1">&#8230;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
<p>A outra forma de se habilitar o modo de <em>debug</em> é fornecer o parâmetro <code>--debug</code> ao iniciar o domínio. Por exemplo:</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">asadmin start-domain &#8211;debug domain1</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
<h3>Conectando o debugger da IDE ao servidor</h3>
<p>Agora, basta usar os recursos de <em>debugging</em> presentes na sua IDE Java para debugar o código. Por exemplo, se você usa o <a href="http://netbeans.org/" onclick="javascript:urchinTracker ('/outbound/article/netbeans.org');">NetBeans</a> 5.5, basta acessar o menu <em>Run - Attach Debugger&#8230;</em> e o configurar da seguinte forma:</p>
<div id="attachment_344" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.danielfmartins.com/wp-content/uploads/2008/09/screenshot-attach.png" ><img src="http://blog.danielfmartins.com/wp-content/uploads/2008/09/screenshot-attach-300x152.png" alt="Anexando debugger do Netbeans" title="Anexar debugger" width="300" height="152" class="size-medium wp-image-344" /></a><p class="wp-caption-text">Anexando debugger do Netbeans</p></div>
<p>O procedimento é semelhante em outras IDEs Java.</p>
<p>Pronto! Feito isso, é só colocar os <em>breakpoints</em> e disparar a execução do código problemático.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.danielfmartins.com/2008/06/10/depurando-uma-aplicacao-javaee-no-glassfish/feed/</wfw:commentRss>
		</item>
		<item>
		<title>PyGod: Como sacanear seus amigos com Python!</title>
		<link>http://blog.danielfmartins.com/2008/05/28/pygod-como-sacanear-seus-amigos-com-python/</link>
		<comments>http://blog.danielfmartins.com/2008/05/28/pygod-como-sacanear-seus-amigos-com-python/#comments</comments>
		<pubDate>Thu, 29 May 2008 00:36:40 +0000</pubDate>
		<dc:creator>Daniel F. Martins</dc:creator>
		
		<category><![CDATA[off-topic]]></category>

		<category><![CDATA[programação]]></category>

		<category><![CDATA[aplicação]]></category>

		<category><![CDATA[curses]]></category>

		<category><![CDATA[inutilitário]]></category>

		<category><![CDATA[linux]]></category>

		<category><![CDATA[programa]]></category>

		<category><![CDATA[pt-br]]></category>

		<category><![CDATA[python]]></category>

		<category><![CDATA[terminal]]></category>

		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://blog.danielfmartins.com/?p=332</guid>
		<description><![CDATA[Pouco tempo depois de ganhar meu primeiro computador, um super 486 DX2 com 16MB de RAM, eu já tinha uma coleção razoável de disquetes onde eu armazenava tudo que era porcaria que eu encontrasse por aí, como fotos (é, esse tipo de foto mesmo), jogos e programas.
Toda coleção de disquetes digna de respeito compartilhava pelo [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://blog.danielfmartins.com/wp-content/uploads/2008/05/psych.jpg'><img src="http://blog.danielfmartins.com/wp-content/uploads/2008/05/psych.jpg" alt="Hmmm... isso aí é uma bichooooona!" title="psych" width="188" height="250" class="alignleft size-full wp-image-337" /></a>Pouco tempo depois de ganhar meu primeiro computador, um super 486 DX2 com 16MB de RAM, eu já tinha uma coleção razoável de disquetes onde eu armazenava tudo que era porcaria que eu encontrasse por aí, como fotos (é, esse tipo de foto mesmo), jogos e programas.</p>
<p>Toda coleção de disquetes digna de respeito compartilhava pelo menos uma característica em comum: dúzias dos já infames programas <em>inutilitários</em>. E a lista era longa, indo desde aqueles programas que mostram a ovelha Dolly andando pela tela até aqueles que fingem formatar o HD. (que atire a primeira pedra quem nunca enviou um desses para os &#8220;amigos&#8221;!)</p>
<p>Mas enfim, os meus inutilitários favoritos eram aqueles programas &#8220;inteligentes&#8221;, que pareciam ter a resposta para qualquer pergunta. Já perdi a conta de quantas vezes eu ouvi a frase <em>&#8220;mas cadê a câmera?&#8221;</em> ao mostrar esses programas para amigos e familiares! Ah, bons tempos aqueles&#8230; <img src='http://blog.danielfmartins.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Foi tomado por esse espírito de nostalgia que eu tive a idéia de tentar implementar um programa parecido em <a href="http://python.org/" onclick="javascript:urchinTracker ('/outbound/article/python.org');">Python</a>. O resultado dessa brincadeira, que chamei de <a href="http://blog.danielfmartins.com/aplicacoes/" >PyGod</a> por razões óbvias, pode ser conferido neste <em>post</em>! </p>
<h3>O programa</h3>
<p>A mecânica por trás desse tipo de programa é super simples. Cada tecla pressionada pelo usuário pode fazer com que o programa alterne entre dois &#8220;modos&#8221;:o <strong>modo de resposta</strong> e o <strong>modo de eco</strong>. No primeiro modo, o programa imprime uma pergunta aleatória na tela enquanto lê a resposta; já o segundo modo simplesmente ecoa as teclas pressionadas pelo usuário.</p>
<p>Os exemplos a seguir devem ajudá-lo a compreender melhor o que acontece.</p>
<h4>1. Modo de resposta</h4>
<p>A tela abaixo mostra como o programa reage a um usuário que conhece o truque.</p>
<p><a href='http://blog.danielfmartins.com/wp-content/uploads/2008/05/pygod2.png'><img src="http://blog.danielfmartins.com/wp-content/uploads/2008/05/pygod2-300x208.png" alt="Modo de resposta" title="PyGod" width="300" height="208" class="alignnone size-medium wp-image-336" /></a></p>
<p>Primeiramente, eu pressionei a tecla <code>;</code> para entrar no modo de resposta. Em seguida, digitei a resposta (<code>Daniel</code>) para a pergunta desejada. Note que, conforme a resposta é digitada, o programa imprime uma pergunta pré-definida de modo que todos pensem que é você quem está digitando aquilo! Então, depois de digitada a resposta, eu pressionei a tecla <code>;</code> novamente para voltar para o modo de eco (ver abaixo) e completei a pergunta.</p>
<h4>2. Modo de eco</h4>
<p>Já a tela abaixo mostra como o programa reage a um usuário que não conhece o truque.</p>
<p><a href='http://blog.danielfmartins.com/wp-content/uploads/2008/05/pygod1.png'><img src="http://blog.danielfmartins.com/wp-content/uploads/2008/05/pygod1-300x208.png" alt="Modo de eco" title="PyGod" width="300" height="208" class="alignnone size-medium wp-image-335" /></a></p>
<p>Como a resposta não foi digitada, o programa mostra uma mensagem qualquer.</p>
<h3>Implementação</h3>
<p>Grande parte do programa se resume a código para manipular o terminal através do módulo <a href="http://www.amk.ca/python/howto/curses/" onclick="javascript:urchinTracker ('/outbound/article/www.amk.ca');">curses</a>. A aplicação foi desenvolvida em Python 2.5.2 e testada no <a href="http://ubuntu.com/" onclick="javascript:urchinTracker ('/outbound/article/ubuntu.com');">Ubuntu</a> 8.04 LTS.</p>
<p>O código do programa está disponível para <em>download</em> na <a href="http://blog.danielfmartins.com/aplicacoes/" >página de aplicações</a> aqui do blog.</p>
<p>* PS: digite <code>wtf</code> e pressione <code>ENTER</code> para ver uma mensagem de ajuda!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.danielfmartins.com/2008/05/28/pygod-como-sacanear-seus-amigos-com-python/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Squeak By Example em pt_BR? Saiba como contribuir!</title>
		<link>http://blog.danielfmartins.com/2008/04/25/squeak-by-example-em-pt_br-saiba-como-contribuir/</link>
		<comments>http://blog.danielfmartins.com/2008/04/25/squeak-by-example-em-pt_br-saiba-como-contribuir/#comments</comments>
		<pubDate>Fri, 25 Apr 2008 04:43:44 +0000</pubDate>
		<dc:creator>Daniel F. Martins</dc:creator>
		
		<category><![CDATA[programação]]></category>

		<category><![CDATA[livro]]></category>

		<category><![CDATA[projeto]]></category>

		<category><![CDATA[pt-br]]></category>

		<category><![CDATA[revisão]]></category>

		<category><![CDATA[smalltalk]]></category>

		<category><![CDATA[software livre]]></category>

		<category><![CDATA[squeak]]></category>

		<category><![CDATA[tradução]]></category>

		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://blog.danielfmartins.com/?p=330</guid>
		<description><![CDATA[É isso aí! Depois de um longo tempo sem dar as caras por aqui, venho aqui anunciar minha mais nova contribuição ao mundo do código aberto: a tradução para o Português do Brasil do livro Squeak By Example. O projeto, iniciado pelo Ronaldo Ferraz, servirá para facilitar o acesso ao Squeak (e ao Smalltalk de [...]]]></description>
			<content:encoded><![CDATA[<p>É isso aí! Depois de um longo tempo sem dar as caras por aqui, venho aqui anunciar minha mais nova contribuição ao mundo do código aberto: <a href="http://logbr.reflectivesurface.com/2008/04/23/traducao-do-squeak-by-example/" onclick="javascript:urchinTracker ('/outbound/article/logbr.reflectivesurface.com');">a tradução para o Português do Brasil</a> do livro <a href="http://squeakbyexample.org/" onclick="javascript:urchinTracker ('/outbound/article/squeakbyexample.org');">Squeak By Example</a>. O projeto, iniciado pelo <a href="http://logbr.reflectivesurface.com/" onclick="javascript:urchinTracker ('/outbound/article/logbr.reflectivesurface.com');">Ronaldo Ferraz</a>, servirá para facilitar o acesso ao <a href="http://squeak.org/" onclick="javascript:urchinTracker ('/outbound/article/squeak.org');">Squeak</a> (e ao <a href="http://pt.wikipedia.org/wiki/Smalltalk" onclick="javascript:urchinTracker ('/outbound/article/pt.wikipedia.org');">Smalltalk</a> de um modo geral) por parte daqueles que não falam Inglês.</p>
<p><strong>Update:</strong> O Ronaldo criou <a href="http://logbr.reflectivesurface.com/2008/04/25/traducao-do-squeak-by-example-instrucoes/" onclick="javascript:urchinTracker ('/outbound/article/logbr.reflectivesurface.com');">um post</a> com algumas dicas para quem usa Mac OS X e gostaria de contribuir com o projeto.</p>
<h3>Legal, eu gostaria de contribuir com o projeto! O que devo fazer?</h3>
<p>Eu uso o <a href="http://ubuntu.com/" onclick="javascript:urchinTracker ('/outbound/article/ubuntu.com');">Ubuntu</a> na minha máquina, portanto mostrarei abaixo como fazer para configurar o ambiente necessário nesse sistema, embora as mesmas instruções devam servir para qualquer Sistema Operacional baseado no <a href="http://debian.org/" onclick="javascript:urchinTracker ('/outbound/article/debian.org');">Debian</a>.</p>
<h4>1. Instalando os pacotes necessários</h4>
<p>O livro Squeak By Example foi criado usando uma fantástica ferramenta que muitos já ouviram falar mas poucos de fato a usaram: <a href="http://www.tex-br.org/" onclick="javascript:urchinTracker ('/outbound/article/www.tex-br.org');">TeX</a>. Não explicarei aqui para que serve essa ferramenta; uma busca no <a href="http://google.com" onclick="javascript:urchinTracker ('/outbound/article/google.com');">Google</a> é o suficiente para você ter uma boa idéia do que se trata.</p>
<p>Além do TeX, precisamos instalar o <a href="http://git.or.cz/" onclick="javascript:urchinTracker ('/outbound/article/git.or.cz');">Git</a>, o sistema de controle de versões usado para gerenciar as alterações nos arquivos durante o processo de tradução e revisão.</p>
<p><strong>Update:</strong> Percebi que também existe um script <a href="http://ruby-lang.org/" onclick="javascript:urchinTracker ('/outbound/article/ruby-lang.org');">Ruby</a> que é executado sempre que o livro é compilado. Por esse motivo, também precisamos instalar o Ruby.</p>
<p>Se você usa Ubuntu, basta rodar o comando abaixo para instalar todas as ferramentas necessárias:</p>
<pre class="terminal">
sudo apt-get install tetex-base tetex-bin tetex-extra lmodern git-core ruby
</pre>
<p>Agora levante e vá dar uma volta com o cachorro ou espere os mais de 200 MB em pacotes baixarem da Internet!</p>
<h4>2. Criando uma conta no Gitorious</h4>
<p>Apesar do projeto original em Inglês usar o Subversion, o Ronaldo optou por hospedar o projeto no <a href="http://gitorious.org/" onclick="javascript:urchinTracker ('/outbound/article/gitorious.org');">Gitorious</a>, um repositório Git para projetos de código aberto.</p>
<p>Criar uma conta no Gitorious é bem simples; basta acessar o site, clicar no link <code>Register</code> e enviar o formulário de cadastro. Após alguns minutos você receberá um e-mail com instruções para ativação do cadastro.</p>
<h4>3. Criando um par de chaves SSH</h4>
<p>O Gitorious usa SSH para autenticar operações realizadas em seus repositórios.</p>
<p>Dê uma olhada no seu diretório <code>~/.ssh</code>, pois é bem provável que você já tenha um par de chaves SSH criado. Se for o caso, pule para o próximo item; se não for o caso, continue lendo.</p>
<p>Para criar um par de chaves SSH basta seguir o exemplo:</p>
<pre class="terminal">
daniel@darkstar:~$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/daniel/.ssh/id_rsa): [enter]
Enter passphrase (empty for no passphrase): [sua senha]
Enter same passphrase again: [sua senha]
Your identification has been saved in /home/daniel/.ssh/id_rsa.
Your public key has been saved in /home/daniel/.ssh/id_rsa.pub.
The key fingerprint is:
00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
</pre>
<h4>4. Importando sua chave pública no Gitorious</h4>
<p>Precisamos agora importar no Gitorious a nossa chave pública. Para isso, acesse o link <code>My account</code> e depois clique no menu <code>Add SSH key</code>. A tela a seguir mostrará um campo de texto, no qual você deve colar o conteúdo da sua chave pública (ex: <code>~/.ssh/id_rsa.pub</code>). Feito isso, basta clicar no botão <code>save</code> para enviar a chave.</p>
<p>A partir deste momento, se o Gitorious lhe pedir uma senha conforme você trabalha com o repositório, basta você digitar a senha dessa chave SSH.</p>
<h4>5. Clonando o repositório do projeto de tradução</h4>
<p>A princípio, o repositório principal criado pelo Ronaldo só será aberto a commits de terceiros em algum momento futuro, e somente àqueles que participarem mais ativamente do processo de tradução e/ou revisão. Portanto você deve criar um &#8220;clone&#8221; desse repositório para que você possa trabalhar em paralelo. Então, eventualmente seus avanços serão revisados e incorporados ao repositório principal.</p>
<p>Para clonar o repositório principal, basta acessar <a href="http://gitorious.org/projects/squeak-by-example/repos/mainline" onclick="javascript:urchinTracker ('/outbound/article/gitorious.org');">esta página</a> e clicar no link <code>Clone repository</code>. Especifique um nome para seu &#8220;clone&#8221; e pressione o botão <code>Clone repository</code>.</p>
<p>Aguarde alguns momentos até que seu &#8220;clone&#8221; fique pronto. Depois que você conseguir acessar a página do seu clone, copie a URL de Push (ex: <code>git@gitorious.org:squeak-by-example/xxx.git</code>) do seu clone e a coloque no seguinte comando, no terminal:</p>
<pre class="terminal">
daniel@darkstar:~$ git clone [url do seu clone]
</pre>
<p>Pegue o seu cachorro e o leve para um novo passeio enquanto o repositório é baixado da Internet.</p>
<h4>6. Compilando o documento</h4>
<p>Agora vem a parte fácil. Depois de baixar o repositório, basta acessar o diretório <code>PortugueseBook</code> e compilar o documento usando o comando <code>make</code>:</p>
<pre class="terminal">
daniel@darkstar:~/...$ cd [seu clone]/PortugueseBook/
daniel@darkstar:~/...$ make
...
</pre>
<p>Não se preocupe se um monte de caracteres estranhos aparecerem na tela. Basta aguardar alguns segundos até que a compilação do documento seja concluída.</p>
<p>Para ver o resultado, basta visualizar o PDF no seu programa preferido:</p>
<pre class="terminal">
daniel@darkstar:~/...$ evince SBE.pdf
</pre>
<h4>7. Reservando capítulos para tradução e revisão</h4>
<p>Entre em contato através dos comentários caso você queira <strong>realmente</strong> contribuir com o projeto. Mas não marque bobeira, pois as vagas são limitadas!</p>
<p>Se você tem uma conta no Google, informe também seu nome de usuário para que eu possa liberar seu acesso de edição na nossa <a href="http://spreadsheets.google.com/ccc?key=p5eXan0YBYDI9UuLbViCpWw&#038;hl=en" onclick="javascript:urchinTracker ('/outbound/article/spreadsheets.google.com');">planilha de acompanhamento</a>.</p>
<p><strong>Atenção:</strong> Vale lembrar que não precisamos somente de tradutores, mas também de <strong>revisores</strong>. Portanto, se você não sabe Inglês, mas conhece Português bem o suficiente para ajudar na correção de erros, sua ajuda é mais que bem-vinda!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.danielfmartins.com/2008/04/25/squeak-by-example-em-pt_br-saiba-como-contribuir/feed/</wfw:commentRss>
		</item>
		<item>
		<title>TDD e Swing juntos?</title>
		<link>http://blog.danielfmartins.com/2008/04/11/tdd-e-swing-juntos/</link>
		<comments>http://blog.danielfmartins.com/2008/04/11/tdd-e-swing-juntos/#comments</comments>
		<pubDate>Fri, 11 Apr 2008 03:00:37 +0000</pubDate>
		<dc:creator>Daniel F. Martins</dc:creator>
		
		<category><![CDATA[programação]]></category>

		<category><![CDATA[conversor]]></category>

		<category><![CDATA[fest]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[junit]]></category>

		<category><![CDATA[netbeans]]></category>

		<category><![CDATA[swing]]></category>

		<category><![CDATA[tdd]]></category>

		<category><![CDATA[temperaturas]]></category>

		<category><![CDATA[testing]]></category>

		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://blog.danielfmartins.com/2007/04/06/tdd-e-swing-juntos/</guid>
		<description><![CDATA[Como prometido, deixarei aqui algumas dicas sobre como desenvolver uma aplicação Swing de conversão de temperaturas utilizando uma técnica de desenvolvimento de software conhecida como TDD (Test Driven Development). Então, se você nunca ouviu falar em TDD antes, procure dar uma estudada para saber do que se trata antes continuar lendo este texto. Garanto que, [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright" src='http://blog.danielfmartins.com/wp-content/uploads/2007/04/257108717_ae23252be0_m.jpg' alt='257108717_ae23252be0_m.jpg' />Como <a href="http://blog.danielfmartins.com/2007/03/22/espalhando-a-palavra/" >prometido</a>, deixarei aqui algumas dicas sobre como desenvolver uma aplicação Swing de conversão de temperaturas utilizando uma técnica de desenvolvimento de <em>software</em> conhecida como TDD (<a href="http://en.wikipedia.org/wiki/Test_driven_development" onclick="javascript:urchinTracker ('/outbound/article/en.wikipedia.org');">Test Driven Development</a>). Então, se você nunca ouviu falar em TDD antes, procure dar uma estudada para saber do que se trata antes continuar lendo este texto. Garanto que, por mais esquisito que esse negócio de TDD possa parecer, é um jeito bem interessante de se desenvolver aplicações.</p>
<p>Não escreverei um passo-a-passo por questões de espaço, mas, basicamente, a seqüência que seguiremos no decorrer do texto será a seguinte: primeiramente, criaremos testes de unidade com o <a href="http://www.junit.org/" onclick="javascript:urchinTracker ('/outbound/article/www.junit.org');">JUnit</a> para definir a lógica para conversão de uma temperatura para outras escalas (<a href="http://en.wikipedia.org/wiki/Celsius" onclick="javascript:urchinTracker ('/outbound/article/en.wikipedia.org');">Celsius</a>, <a href="http://en.wikipedia.org/wiki/Kelvin" onclick="javascript:urchinTracker ('/outbound/article/en.wikipedia.org');">Kelvin</a> e <a href="http://en.wikipedia.org/wiki/Fahrenheit" onclick="javascript:urchinTracker ('/outbound/article/en.wikipedia.org');">Fahrenheit</a>). Em seguida, iremos programar essa lógica até que todos os testes passem. Depois disso, a interface com o usuário será desenhada e o seu comportamento definido, através da criação de testes JUnit + <a href="http://fest.easytesting.org/swing/wiki/pmwiki.php" onclick="javascript:urchinTracker ('/outbound/article/fest.easytesting.org');">FEST-Swing</a>, ferramenta esta muito interessante que permite automatizar testes em aplicações Swing. Por fim, programaremos a lógica da <em>View</em> até que todos os testes passem. E qual será o resultado dessa bagunça toda? Uma aplicação funcional.</p>
<p>É, eu sei&#8230; na teoria tudo parece muito bonito, mas, e na prática? Será que funciona assim mesmo? Se está curioso, então continue lendo! </p>
<h3>Ferramentas e arquivos</h3>
<p>Como <acronym title="Integrated Development Environment">IDE</acronym>, utilizaremos o <a href="http://www.netbeans.org/" onclick="javascript:urchinTracker ('/outbound/article/www.netbeans.org');">NetBeans 6.1</a> pela facilidade em se desenvolver aplicações <em>desktop</em>. Você também precisará baixar <a href="http://code.google.com/p/fest/downloads/list" onclick="javascript:urchinTracker ('/outbound/article/code.google.com');">baixar</a> a última distribuição do FEST-Swing e adicioná-la no seu NetBeans através do <em>Library Manager</em>.</p>
<p>O código-fonte completo da aplicação mostrada aqui pode ser baixado através da <a href="http://blog.danielfmartins.com/aplicacoes" >página de aplicações</a> aqui do <em>blog</em>.</p>
<h3>Definindo a lógica de conversão de temperatura</h3>
<p>Vamos pensar agora em como a lógica de conversão de temperatura deve funcionar. Para tornar mais fácil a tarefa de se obter uma arquitetura limpa e &#8220;coerente&#8221;, escrevemos os testes unitários antes do código que implementa a lógica de conversão.</p>
<p>Isso mesmo, primeiro os testes e depois a implementação. Se você tivesse lido um pouco sobre TDD, provavelmente não teria se espantado tanto! Abaixo, um trecho do livro <a href="http://www.submarino.com.br/books_productdetails.asp?Query=ProductPage&#038;ProdTypeId=1&#038;ProdId=225051&#038;ST=SE&#038;franq=170707" onclick="javascript:urchinTracker ('/outbound/article/www.submarino.com.br');">Extreme Programming</a>, de <a href="http://blog.improveit.com.br/" onclick="javascript:urchinTracker ('/outbound/article/blog.improveit.com.br');">Vinícios Manhães Teles</a>:</p>
<blockquote><p>
Quando o desenvolvedor pensa no teste antes de pensar na implementação, ele é forçado a compreender melhor o problema [...]. Ao se aprofundar no problema, o desenvolvedor está fazendo uma análise mais detalhada. Portanto, neste momento, o desenvolvimento guiado por testes (TDD) atua como uma técnica de análise [...].</p>
<p>Quando o desenvolvedor escreve o teste, ele procura atuar como um cliente dele, se preocupando apenas com a interface externa do método, sem dar atenção à implementação. Isso é ótimo porque permite que o design do método seja o mais adequado possível para aqueles que irão utilizá-lo. [...]
</p></blockquote>
<p>Isso faz sentido para você ou não? Para mim - e para dezenas de milhares de outros desenvolvedores - faz muito sentido!</p>
<p>Nem preciso dizer que este livro é obrigatório para aqueles que querem aprender, de uma vez por todas, as práticas do <acronym title="eXtreme Programming">XP</acronym>. Sei que não estou ganhando nada pela propaganda, mas é que o livro é muito bom mesmo! Faço propaganda dele até de graça. <img src='http://blog.danielfmartins.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p>Continuando, confira abaixo os testes que servirão, ao mesmo tempo, para definir o <em>design</em> do código de conversão e testá-lo:</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">package</span> com.<span class="me1">danielfmartins</span>.<span class="me1">blog</span>.<span class="me1">tutorial</span>.<span class="me1">tdd</span>.<span class="me1">fest</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// imports &#8230;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">public</span> <span class="kw2">class</span> ConversorTemperaturaImplTest <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">private</span> ConversorTemperatura conversion;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; @Before</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw4">void</span> setUp<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; conversion = <span class="kw2">new</span> ConversorTemperaturaImpl<span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; @Test</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw4">void</span> converterParaCelsius<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; assertEquals<span class="br0">&#40;</span>conversion.<span class="me1">converter</span><span class="br0">&#40;</span><span class="nu0">15.0</span>, Escala.<span class="me1">CELSIUS</span>, Escala.<span class="me1">CELSIUS</span><span class="br0">&#41;</span>, <span class="nu0">15.0</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; assertEquals<span class="br0">&#40;</span>conversion.<span class="me1">converter</span><span class="br0">&#40;</span><span class="nu0">50.0</span>, Escala.<span class="me1">FAHRENHEIT</span>, Escala.<span class="me1">CELSIUS</span><span class="br0">&#41;</span>, <span class="nu0">10.0</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; assertEquals<span class="br0">&#40;</span>conversion.<span class="me1">converter</span><span class="br0">&#40;</span><span class="nu0">561.5</span>, Escala.<span class="me1">KELVIN</span>, Escala.<span class="me1">CELSIUS</span><span class="br0">&#41;</span>, <span class="nu0">288.35</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @Test</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw4">void</span> converterParaFahrenheit<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; assertEquals<span class="br0">&#40;</span>conversion.<span class="me1">converter</span><span class="br0">&#40;</span><span class="nu0">15.0</span>, Escala.<span class="me1">CELSIUS</span>, Escala.<span class="me1">FAHRENHEIT</span><span class="br0">&#41;</span>, <span class="nu0">59.0</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; assertEquals<span class="br0">&#40;</span>conversion.<span class="me1">converter</span><span class="br0">&#40;</span><span class="nu0">50.0</span>, Escala.<span class="me1">FAHRENHEIT</span>, Escala.<span class="me1">FAHRENHEIT</span><span class="br0">&#41;</span>, <span class="nu0">50.0</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; assertEquals<span class="br0">&#40;</span>conversion.<span class="me1">converter</span><span class="br0">&#40;</span><span class="nu0">561.5</span>, Escala.<span class="me1">KELVIN</span>, Escala.<span class="me1">FAHRENHEIT</span><span class="br0">&#41;</span>, <span class="nu0">551.03</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @Test</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw4">void</span> converterParaKelvin<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; assertEquals<span class="br0">&#40;</span>conversion.<span class="me1">converter</span><span class="br0">&#40;</span><span class="nu0">15.0</span>, Escala.<span class="me1">CELSIUS</span>, Escala.<span class="me1">KELVIN</span><span class="br0">&#41;</span>, <span class="nu0">288.15</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; assertEquals<span class="br0">&#40;</span>conversion.<span class="me1">converter</span><span class="br0">&#40;</span><span class="nu0">50.0</span>, Escala.<span class="me1">FAHRENHEIT</span>, Escala.<span class="me1">KELVIN</span><span class="br0">&#41;</span>, <span class="nu0">283.15</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; assertEquals<span class="br0">&#40;</span>conversion.<span class="me1">converter</span><span class="br0">&#40;</span><span class="nu0">561.5</span>, Escala.<span class="me1">KELVIN</span>, Escala.<span class="me1">KELVIN</span><span class="br0">&#41;</span>, <span class="nu0">561.5</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
<p>Como pôde ser visto, a classe de conversão de temperaturas deverá ser <strong>simples e eficiente para a situação proposta</strong>. Ela terá apenas um método <code>converter()</code> que receberá três parâmetros:</p>
<ul>
<li>Temperatura a ser convertida;</li>
<li>Escala de origem (Celsius, Kelvin ou Fahrenheit); e</li>
<li>Escala de destino (Celsius, Kelvin ou Fahrenheit).</li>
</ul>
<p>Neste momento o que temos é um código todo sublinhado em vermelho. Portanto, nossa tarefa agora é fazer com que eles chegem a pelo menos compilar.</p>
<p>Em primeiro lugar, crie o <em>enum</em> <code>Escala</code>:</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">package</span> com.<span class="me1">danielfmartins</span>.<span class="me1">blog</span>.<span class="me1">tutorial</span>.<span class="me1">tdd</span>.<span class="me1">fest</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">public</span> <span class="kw2">enum</span> Escala <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; CELSIUS, FAHRENHEIT, KELVIN</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
<p>Depois, crie a interface <code>ConversorTemperatura</code>:</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">package</span> com.<span class="me1">danielfmartins</span>.<span class="me1">blog</span>.<span class="me1">tutorial</span>.<span class="me1">tdd</span>.<span class="me1">fest</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">public</span> <span class="kw2">interface</span> ConversorTemperatura <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw4">double</span> converter<span class="br0">&#40;</span><span class="kw4">double</span> valor, Escala de, Escala para<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
<p>Finalmente, crie a classe <code>ConversorTemperaturaImpl</code>:</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">package</span> com.<span class="me1">danielfmartins</span>.<span class="me1">blog</span>.<span class="me1">tutorial</span>.<span class="me1">tdd</span>.<span class="me1">fest</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">public</span> <span class="kw2">class</span> ConversorTemperaturaImpl <span class="kw2">implements</span> ConversorTemperatura <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @Override</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw4">double</span> converter<span class="br0">&#40;</span><span class="kw4">double</span> valor, Escala de, Escala para<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">return</span> <span class="nu0">0.0</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
<p>Neste ponto já temos um código compilado, embora o mesmo não passe nos testes que definimos anteriormente. A tarefa agora é ir alterando este código até que todos aqueles testes passem:</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">package</span> com.<span class="me1">danielfmartins</span>.<span class="me1">blog</span>.<span class="me1">tutorial</span>.<span class="me1">tdd</span>.<span class="me1">fest</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">public</span> <span class="kw2">class</span> ConversorTemperaturaImpl <span class="kw2">implements</span> ConversorTemperatura <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @Override</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw4">double</span> converter<span class="br0">&#40;</span><span class="kw4">double</span> valor, Escala de, Escala para<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">double</span> result = <span class="nu0">0.0</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/* conversão desnecessária */</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>de == para<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">return</span> valor;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>de == Escala.<span class="me1">CELSIUS</span> &amp;&amp; para == Escala.<span class="me1">FAHRENHEIT</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result = valor * <span class="nu0">1.8</span> + <span class="nu0">32</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">&#40;</span>de == Escala.<span class="me1">CELSIUS</span> &amp;&amp; para == Escala.<span class="me1">KELVIN</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result = valor + <span class="nu0">273.15</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">&#40;</span>de == Escala.<span class="me1">FAHRENHEIT</span> &amp;&amp; para == Escala.<span class="me1">CELSIUS</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result = <span class="br0">&#40;</span>valor - <span class="nu0">32</span><span class="br0">&#41;</span> / <span class="nu0">1.8</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">&#40;</span>de == Escala.<span class="me1">FAHRENHEIT</span> &amp;&amp; para == Escala.<span class="me1">KELVIN</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result = <span class="br0">&#40;</span>valor + <span class="nu0">459.67</span><span class="br0">&#41;</span> / <span class="nu0">1.8</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">&#40;</span>de == Escala.<span class="me1">KELVIN</span> &amp;&amp; para == Escala.<span class="me1">CELSIUS</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result = valor - <span class="nu0">273.15</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">&#40;</span>de == Escala.<span class="me1">KELVIN</span> &amp;&amp; para == Escala.<span class="me1">FAHRENHEIT</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result = valor * <span class="nu0">1.8</span> - <span class="nu0">459.67</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">return</span> result;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
<p>Ok, neste momento os testes já devem executar com sucesso, o que significa que terminamos a codificação da lógica de conversão de temperaturas. Podemos então partir para a definição da interface com o usuário.</p>
<h3>Definindo a interface com o usuário</h3>
<p>A melhor forma de saber como o usuário irá interagir com o sistema é criar uma representação da interface com a qual ele irá trabalhar. Isso pode ser feito de diversas formas: desde um rabisco à lápis em uma folha sulfite até através do uso de um <em>software</em>.</p>
<p>No <a href="http://www.netbeans.org/" onclick="javascript:urchinTracker ('/outbound/article/www.netbeans.org');">NetBeans</a>, essa tarefa é muito simples de ser feita, já que contamos com a ajuda do Matisse, o módulo de <acronym title="Graphical User Interface">GUI</acronym> design. Com ele, podemos criar interfaces gráficas complexas em minutos, o que torna esta ferramenta ideal para o trabalho.</p>
<p>Ok, depois de alguns minutos mexendo no Matisse, o resultado que obtive pode ser visto na imagem abaixo:</p>
<p><img src='http://blog.danielfmartins.com/wp-content/uploads/2007/04/tdd01.jpg' alt='tdd01.jpg' /></p>
<p>A interação do usuário com essa tela é bem fácil de se entender. O usuário fornecerá a temperatura a ser convertida (através da digitação do valor e escolha da escala). Em seguida, ele pressionará o botão <em>Converter</em>. Obviamente, o sistema deverá informar o usuário caso ele forneça uma temperatura inválida. Caso a temperatura seja válida, a aplicação faz a conversão e mostra o resultado nas três caixas de texto na parte inferior da tela. Os botões, na parte inferior da tela, explicam suas funções por si só.</p>
<h3>Definindo o comportamento da interface com o usuário</h3>
<p>Antes de programar a interface com o usuário, vamos aplicar uma abordagem semelhante à aplicada para definir a lógica de conversão de temperaturas, ou seja, vamos criar os testes primeiro:</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">package</span> com.<span class="me1">danielfmartins</span>.<span class="me1">blog</span>.<span class="me1">tutorial</span>.<span class="me1">tdd</span>.<span class="me1">fest</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// imports &#8230;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">public</span> <span class="kw2">class</span> ConversorFrameTest <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">private</span> FrameFixture frame;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; @Before</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw4">void</span> setUp<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame = <span class="kw2">new</span> FrameFixture<span class="br0">&#40;</span><span class="kw2">new</span> ConversorFrame<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">show</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @After</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw4">void</span> tearDown<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">cleanUp</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @Test</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw4">void</span> checarValoresIniciais<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">textBox</span><span class="br0">&#40;</span><span class="st0">&quot;temperatura&quot;</span><span class="br0">&#41;</span>.<span class="me1">requireText</span><span class="br0">&#40;</span><span class="st0">&quot;0.0&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">textBox</span><span class="br0">&#40;</span><span class="st0">&quot;celsius&quot;</span><span class="br0">&#41;</span>.<span class="me1">requireText</span><span class="br0">&#40;</span><span class="st0">&quot;0.0&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">textBox</span><span class="br0">&#40;</span><span class="st0">&quot;fahrenheit&quot;</span><span class="br0">&#41;</span>.<span class="me1">requireText</span><span class="br0">&#40;</span><span class="st0">&quot;0.0&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">textBox</span><span class="br0">&#40;</span><span class="st0">&quot;kelvin&quot;</span><span class="br0">&#41;</span>.<span class="me1">requireText</span><span class="br0">&#40;</span><span class="st0">&quot;0.0&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">comboBox</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">requireSelection</span><span class="br0">&#40;</span>Escala.<span class="me1">CELSIUS</span>.<span class="me1">toString</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; @Test</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw4">void</span> converterTemperaturaVazia<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">textBox</span><span class="br0">&#40;</span><span class="st0">&quot;temperatura&quot;</span><span class="br0">&#41;</span>.<span class="me1">deleteText</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">comboBox</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">selectItem</span><span class="br0">&#40;</span>Escala.<span class="me1">FAHRENHEIT</span>.<span class="me1">toString</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">button</span><span class="br0">&#40;</span><span class="st0">&quot;converter&quot;</span><span class="br0">&#41;</span>.<span class="me1">click</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">optionPane</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">requireErrorMessage</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">okButton</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">click</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @Test</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw4">void</span> converterTemperaturaInvalida<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">textBox</span><span class="br0">&#40;</span><span class="st0">&quot;temperatura&quot;</span><span class="br0">&#41;</span>.<span class="me1">deleteText</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">enterText</span><span class="br0">&#40;</span><span class="st0">&quot;aaa&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">button</span><span class="br0">&#40;</span><span class="st0">&quot;converter&quot;</span><span class="br0">&#41;</span>.<span class="me1">click</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">optionPane</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">requireErrorMessage</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">okButton</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">click</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; @Test</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw4">void</span> converterDeFahrenheit<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">textBox</span><span class="br0">&#40;</span><span class="st0">&quot;temperatura&quot;</span><span class="br0">&#41;</span>.<span class="me1">deleteText</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">enterText</span><span class="br0">&#40;</span><span class="st0">&quot;50.0&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">comboBox</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">selectItem</span><span class="br0">&#40;</span>Escala.<span class="me1">FAHRENHEIT</span>.<span class="me1">toString</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">button</span><span class="br0">&#40;</span><span class="st0">&quot;converter&quot;</span><span class="br0">&#41;</span>.<span class="me1">click</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">textBox</span><span class="br0">&#40;</span><span class="st0">&quot;celsius&quot;</span><span class="br0">&#41;</span>.<span class="me1">requireText</span><span class="br0">&#40;</span><span class="st0">&quot;10.0&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">textBox</span><span class="br0">&#40;</span><span class="st0">&quot;fahrenheit&quot;</span><span class="br0">&#41;</span>.<span class="me1">requireText</span><span class="br0">&#40;</span><span class="st0">&quot;50.0&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">textBox</span><span class="br0">&#40;</span><span class="st0">&quot;kelvin&quot;</span><span class="br0">&#41;</span>.<span class="me1">requireText</span><span class="br0">&#40;</span><span class="st0">&quot;283.15&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @Test</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw4">void</span> converterDeKelvin<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">textBox</span><span class="br0">&#40;</span><span class="st0">&quot;temperatura&quot;</span><span class="br0">&#41;</span>.<span class="me1">deleteText</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">enterText</span><span class="br0">&#40;</span><span class="st0">&quot;450.2&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">comboBox</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">selectItem</span><span class="br0">&#40;</span>Escala.<span class="me1">KELVIN</span>.<span class="me1">toString</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">button</span><span class="br0">&#40;</span><span class="st0">&quot;converter&quot;</span><span class="br0">&#41;</span>.<span class="me1">click</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">textBox</span><span class="br0">&#40;</span><span class="st0">&quot;celsius&quot;</span><span class="br0">&#41;</span>.<span class="me1">requireText</span><span class="br0">&#40;</span><span class="st0">&quot;177.05&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">textBox</span><span class="br0">&#40;</span><span class="st0">&quot;fahrenheit&quot;</span><span class="br0">&#41;</span>.<span class="me1">requireText</span><span class="br0">&#40;</span><span class="st0">&quot;350.69&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">textBox</span><span class="br0">&#40;</span><span class="st0">&quot;kelvin&quot;</span><span class="br0">&#41;</span>.<span class="me1">requireText</span><span class="br0">&#40;</span><span class="st0">&quot;450.2&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @Test</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw4">void</span> converterDeCelsius<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">textBox</span><span class="br0">&#40;</span><span class="st0">&quot;temperatura&quot;</span><span class="br0">&#41;</span>.<span class="me1">deleteText</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">enterText</span><span class="br0">&#40;</span><span class="st0">&quot;50.5&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">comboBox</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">selectItem</span><span class="br0">&#40;</span>Escala.<span class="me1">CELSIUS</span>.<span class="me1">toString</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">button</span><span class="br0">&#40;</span><span class="st0">&quot;converter&quot;</span><span class="br0">&#41;</span>.<span class="me1">click</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">textBox</span><span class="br0">&#40;</span><span class="st0">&quot;celsius&quot;</span><span class="br0">&#41;</span>.<span class="me1">requireText</span><span class="br0">&#40;</span><span class="st0">&quot;50.5&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">textBox</span><span class="br0">&#40;</span><span class="st0">&quot;fahrenheit&quot;</span><span class="br0">&#41;</span>.<span class="me1">requireText</span><span class="br0">&#40;</span><span class="st0">&quot;122.9&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">textBox</span><span class="br0">&#40;</span><span class="st0">&quot;kelvin&quot;</span><span class="br0">&#41;</span>.<span class="me1">requireText</span><span class="br0">&#40;</span><span class="st0">&quot;323.65&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @Test</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw4">void</span> mostrarJanelaSobre<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">button</span><span class="br0">&#40;</span><span class="st0">&quot;sobre&quot;</span><span class="br0">&#41;</span>.<span class="me1">click</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">optionPane</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">requireInformationMessage</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">okButton</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">click</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @Test</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw4">void</span> fecharAplicativo<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">button</span><span class="br0">&#40;</span><span class="st0">&quot;sair&quot;</span><span class="br0">&#41;</span>.<span class="me1">click</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">assert</span> !frame.<span class="me1">component</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">isVisible</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
</ol>
</div>
<p>Uma das características mais marcantes do FEST-Swing é o uso de <a href="http://martinfowler.com/bliki/FluentInterface.html" onclick="javascript:urchinTracker ('/outbound/article/martinfowler.com');">interfaces fluentes</a> na <acronym title="Application Programming Interface">API</acronym>, tornando muito simples a criação dos testes antes mesmo de criarmos a interface com o usuário.</p>
<p>Agora vamos dar uma olhada rápida no código. Primeiramente, antes de cada teste ser executado, o método <code>setUp()</code> cria um objeto <code>FrameFixture</code> passando uma nova instância do <code>Frame</code> que desejamos testar. É através desse objeto <em>fixture</em> que podemos realizar asserções em elementos da interface gráfica.</p>
<p>No nosso caso, utilizamos uma instância de <code>FrameFixture</code> pois estamos testando um objeto <code>Frame</code>. Entretanto, existem diversos outros tipos de <em>fixtures</em> que permitem testar outros componentes (<code>Dialog</code>, <code>JOptionPane</code> etc).</p>
<p>Como os métodos do objeto <em>fixture</em> são basicamente instruções dadas a um usuário &#8220;de mentira&#8221;, fica muito fácil adivinhar o que acontece em cada um dos testes. Perceba que todas essas instruções seguem um padrão: informamos o componente desejado, disparamos ações nesse componente e verificamos a resposta do componente controlado pela <em>fixture</em>.</p>
<p>Finalmente, o método <code>tearDown()</code> libera os recursos utilizados por cada teste.</p>
<p>Ok, você pode executar os testes agora. Não se espante quando seu teclado e mouse ganharem &#8220;vida&#8221;&#8230; é o FEST-Swing usando sua aplicação!</p>
<h3>Implementando a lógica da interface com o usuário</h3>
<p>Os testes falharam! Por quê? Ora, porque ainda não implementamos a lógica de interação do usuário com a aplicação! Mas, fique tranqüilo, pois é exatamente isto que iremos fazer agora.</p>
<p>Primeiramente, vamos configurar o <em>Model</em> do nosso <code>JComboBox</code> para que este mostre o nosso <em>enum</em> <code>Escala</code>:</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3ADefaultComboBoxModel+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="javascript:urchinTracker ('/outbound/article/www.google.com');"><span class="kw3">DefaultComboBoxModel</span></a><span class="br0">&#40;</span>Escala.<span class="me1">values</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
<p>Adicione um <code>ActionListener</code> no botão <em>Converter</em> com o seguinte código:</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw4">double</span> temp = <span class="nu0">0.0</span>;</div>
</li>
<li class="li1">
<div class="de1">Escala scale = <span class="br0">&#40;</span>Escala<span class="br0">&#41;</span> escala.<span class="me1">getSelectedItem</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">ConversorTemperatura conversor = <span class="kw2">new</span> ConversorTemperaturaImpl<span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// Limpa os resultados anteriores</span></div>
</li>
<li class="li1">
<div class="de1">celsius.<span class="me1">setText</span><span class="br0">&#40;</span><span class="st0">&quot;0.0&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">fahrenheit.<span class="me1">setText</span><span class="br0">&#40;</span><span class="st0">&quot;0.0&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">kelvin.<span class="me1">setText</span><span class="br0">&#40;</span><span class="st0">&quot;0.0&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">try</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; temp = <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3ADouble+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="javascript:urchinTracker ('/outbound/article/www.google.com');"><span class="kw3">Double</span></a>.<span class="me1">valueOf</span><span class="br0">&#40;</span>temperatura.<span class="me1">getText</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>; <span class="co1">// Converte para double</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="coMULTI">/* Mostra os resultados */</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; celsius.<span class="me1">setText</span><span class="br0">&#40;</span><span class="st0">&quot;&quot;</span> + conversor.<span class="me1">converter</span><span class="br0">&#40;</span>temp, scale, Escala.<span class="me1">CELSIUS</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; fahrenheit.<span class="me1">setText</span><span class="br0">&#40;</span><span class="st0">&quot;&quot;</span> + conversor.<span class="me1">converter</span><span class="br0">&#40;</span>temp, scale, Escala.<span class="me1">FAHRENHEIT</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; kelvin.<span class="me1">setText</span><span class="br0">&#40;</span><span class="st0">&quot;&quot;</span> + conversor.<span class="me1">converter</span><span class="br0">&#40;</span>temp, scale, Escala.<span class="me1">KELVIN</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span> <span class="kw2">catch</span> <span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3AException+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="javascript:urchinTracker ('/outbound/article/www.google.com');"><span class="kw3">Exception</span></a> e<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="coMULTI">/* Erro na obtenção da temperatura */</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3AJOptionPane+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="javascript:urchinTracker ('/outbound/article/www.google.com');"><span class="kw3">JOptionPane</span></a>.<span class="me1">showMessageDialog</span><span class="br0">&#40;</span><span class="kw2">this</span>, <span class="st0">&quot;Temperatura inválida&quot;</span>, <span class="st0">&quot;Erro&quot;</span>, <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3AJOptionPane+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="javascript:urchinTracker ('/outbound/article/www.google.com');"><span class="kw3">JOptionPane</span></a>.<span class="me1">ERROR_MESSAGE</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; temperatura.<span class="me1">requestFocus</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
<p>Adicione um <code>ActionListener</code> no botão <em>Sobre&#8230;</em> com o seguinte código:</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3AJOptionPane+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="javascript:urchinTracker ('/outbound/article/www.google.com');"><span class="kw3">JOptionPane</span></a>.<span class="me1">showMessageDialog</span><span class="br0">&#40;</span><span class="kw2">this</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&quot;TDD (Test Driven Development) e Swing?<span class="es0">\n</span>Autor: Daniel F. Martins&quot;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&quot;Sobre&#8230;&quot;</span>, <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3AJOptionPane+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="javascript:urchinTracker ('/outbound/article/www.google.com');"><span class="kw3">JOptionPane</span></a>.<span class="me1">INFORMATION_MESSAGE</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
</ol>
</div>
<p>E, finalmente, adicione um <code>ActionListener</code> (que novidade&#8230;) no botão <em>Sair</em>, com o seguinte código:</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">dispose<span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
<p>Está pronto! Agora todos os testes devem passar, indicando que temos uma aplicação pronta para servir nossos usuários da melhor forma possível.</p>
<h3>Conclusão</h3>
<p>O propósito aqui não é explicar tudo sobre o TDD e suas vantagens e desvantagens, eu deixo essa tarefa para outros textos disponíveis por aí. O que eu tentei fazer aqui foi apenas ilustrar, ou simular, o desenvolvimento de uma aplicação Swing usando TDD, para provar que sim,  é possível desenvolver aplicações Swing de um modo ágil.</p>
<p>Se você costuma ler sobre programação <em>desktop</em>, seja em Java ou em qualquer plataforma, você provavelmente já deve ter ouvido aquela máxima de que é &#8220;impossívell testar interfaces com o usuário&#8221;. Com o FEST-Swing isso nunca foi tão&#8230; <strong>mentira</strong>. <img src='http://blog.danielfmartins.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p class="rights">
Foto por: <a href="http://flickr.com/photos/alainbachellier/" onclick="javascript:urchinTracker ('/outbound/article/flickr.com');">Alain Bachellier</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.danielfmartins.com/2008/04/11/tdd-e-swing-juntos/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Que linguagem você aprenderá em 2008?</title>
		<link>http://blog.danielfmartins.com/2008/01/20/que-linguagem-voce-aprendera-em-2008/</link>
		<comments>http://blog.danielfmartins.com/2008/01/20/que-linguagem-voce-aprendera-em-2008/#comments</comments>
		<pubDate>Mon, 21 Jan 2008 02:34:41 +0000</pubDate>
		<dc:creator>Daniel F. Martins</dc:creator>
		
		<category><![CDATA[off-topic]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[opiniões]]></category>

		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blog.danielfmartins.com/2008/01/20/que-linguagem-voce-aprendera-em-2008/</guid>
		<description><![CDATA[&#8220;Learn one language every year&#8220;. Não me lembro ao certo onde e quando foi a primeira vez que li isso, mas depois de pensar por alguns instantes, eu mudei aquela idéia que eu tinha &#8212; de que é melhor se especializar numa única tecnologia em detrimento das demais. Melhor um peito na mão do que [...]]]></description>
			<content:encoded><![CDATA[<p>&#8220;<em>Learn one language every year</em>&#8220;. Não me lembro ao certo onde e quando foi a primeira vez que li isso, mas depois de pensar por alguns instantes, eu mudei aquela idéia que eu tinha &#8212; de que é melhor se especializar numa única tecnologia em detrimento das demais. Melhor um peito na mão do que dois no sutiã, concorda? <img src='http://blog.danielfmartins.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Voltando aos tempos da faculdade, embora subliminarmente, eu aprendi que <a href="http://java.sun.com" onclick="javascript:urchinTracker ('/outbound/article/java.sun.com');">Java</a> <a href="http://blog.danielfmartins.com/2007/05/22/java-e-cinema-tudo-a-ver/" >é o que há</a>, que <a href="http://en.wikipedia.org/wiki/C_(programming_language)" onclick="javascript:urchinTracker ('/outbound/article/en.wikipedia.org');">C</a> só serve para aprender algoritmos (e estruturas de dados) e que depois de trabalhar como programador eu devo <a href="http://en.wikipedia.org/wiki/The_Dilbert_Principle" onclick="javascript:urchinTracker ('/outbound/article/en.wikipedia.org');">virar gerente</a>. Nada mais justo, afinal, o que esperar de um curso de Sistemas de Informação? (droga, eu devia ter feito Ciências da Computação.)</p>
<p>A cada nova descoberta eu me impressionava mais com as vantagens do Java. Não demorou muito para eu decidisse me &#8220;especializar&#8221; nessa tecnologia; comecei a visitar regularmente sites e <a href="http://javafree.org" onclick="javascript:urchinTracker ('/outbound/article/javafree.org');">fóruns</a> sobre Java, montar pequenos programas, ler livros e estudar para certificações.</p>
<p>Hehehe, pela forma que esse texto vem sendo escrito, você deve estar se perguntando quando é que eu vou parar com essa babação de ovos e começar a contra-argumentar tudo o que disse. O famoso &#8220;mas&#8221;.</p>
<p>Mas&#8230; nada!</p>
<p>Felizmente, não me arrependo de nenhum programa que fiz, de nenhuma certificação que tirei e de nenhum livro que li. O simples uso do Java me ensinou coisas que eu provavelmente nunca aprenderia caso escolhesse outra linguagem. Em outras palavras, Java me ensinou uma coisa que poucos sabem (ou muitos ignoram): <strong>é difícil fazer <em>software</em></strong>.</p>
<p>Se eu vou largar o Java? Talvez&#8230; daqui uns cinco anos. Entretanto, depois de me dedicar ao Java por todo esse tempo, eu percebi que agora é o melhor momento para desacelerar um pouco e olhar mais atentamente o que acontece ao meu redor. Não com o intuito de migrar para outra coisa, mas de ampliar meus horizontes.</p>
<p>Conforme o ano passado se encerrava, eu ia coletando informações aqui e ali a respeito de tecnologias que eu estudaria neste ano de 2008; tentei ver qual delas seria viável a ponto de não ser apenas mais uma diversão nas horas vagas, qual é rica em projetos e bibliotecas, qual é sustentada por uma comunidade organizada e capaz, etc. No fim das contas a única opção que me pareceu interessante foi <a href="http://www.python.org" onclick="javascript:urchinTracker ('/outbound/article/www.python.org');">Python</a>.</p>
<p>Já comecei a ler o <a href="http://www.amazon.com/Learning-Python-3rd-Mark-Lutz/dp/0596513984/ref=pd_bbs_2?ie=UTF8&#038;s=books&#038;qid=1200880772&#038;sr=8-2" onclick="javascript:urchinTracker ('/outbound/article/www.amazon.com');">Learning Python</a>, que é um livro excelente para quem, como eu, nunca viu Python na vida. Minha pouca experiência na linguagem não impediu que eu já encontrasse algumas <em>features</em> interessantes, dentre as quais eu destaco <a href="http://docs.python.org/tut/node7.html#SECTION007140000000000000000" onclick="javascript:urchinTracker ('/outbound/article/docs.python.org');">list comprehensions</a> e <a href="http://docs.python.org/tut/node11.html#SECTION00111000000000000000000" onclick="javascript:urchinTracker ('/outbound/article/docs.python.org');">generators</a>.</p>
<p>Nos próximos meses veremos se essa foi uma boa escolha, mas, de qualquer forma, eu estou confiante. Se tudo correr bem, a comunidade Python brasileira <a href="http://en.wikipedia.org/wiki/Mário_Zagallo" onclick="javascript:urchinTracker ('/outbound/article/en.wikipedia.org');">vai ter que me engolir</a>!</p>
<p>E você, vai aprender uma nova linguagem ou vai continuar nessa? Se optou pela primeira opção, qual é a linguagem e o que o motivou a escolhe-la?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.danielfmartins.com/2008/01/20/que-linguagem-voce-aprendera-em-2008/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Mais um&#8230;</title>
		<link>http://blog.danielfmartins.com/2008/01/07/mais-um/</link>
		<comments>http://blog.danielfmartins.com/2008/01/07/mais-um/#comments</comments>
		<pubDate>Mon, 07 Jan 2008 15:50:17 +0000</pubDate>
		<dc:creator>Daniel F. Martins</dc:creator>
		
		<category><![CDATA[off-topic]]></category>

		<category><![CDATA[api]]></category>

		<category><![CDATA[dados]]></category>

		<category><![CDATA[groovy]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[meta programação]]></category>

		<category><![CDATA[open source]]></category>

		<category><![CDATA[projeto]]></category>

		<guid isPermaLink="false">http://blog.danielfmartins.com/2008/01/07/mais-um/</guid>
		<description><![CDATA[English readers: please follow this link.
Vocês se lembram da minha não-tão-recente experiência com DSLs em Groovy? Pois é&#8230; para variar, eu acho que levei a idéia um pouco longe demais.
Explico. Algum tempo depois de publicar o referido post, eu comecei a procurar na Internet por outras APIs ou aplicações semelhantes à que eu havia criado [...]]]></description>
			<content:encoded><![CDATA[<p><strong>English readers: please <a href="http://blog.danielfmartins.com/2008/01/07/mais-um#eng" >follow this link</a></strong>.</p>
<p>Vocês se lembram da <a href="http://blog.danielfmartins.com/2007/12/17/dsl-rolando-dados-com-o-groovy/" >minha não-tão-recente experiência</a> com <acronym title="Domain Specific Language">DSL</acronym>s em <a href="http://groovy.codehaus.org" onclick="javascript:urchinTracker ('/outbound/article/groovy.codehaus.org');">Groovy</a>? Pois é&#8230; para variar, eu acho que levei a idéia um pouco longe demais.</p>
<p>Explico. Algum tempo depois de publicar o referido <em>post</em>, eu comecei a procurar na Internet por outras <acronym title="Application Programming Interface">API</acronym>s ou aplicações semelhantes à que eu havia criado (por diversão, diga-se de passagem). A não ser por <a href="http://www.realityfault.org/programmer/drp.cgh" onclick="javascript:urchinTracker ('/outbound/article/www.realityfault.org');">uma</a> <a href="http://divnull.com/rollplay/" onclick="javascript:urchinTracker ('/outbound/article/divnull.com');">ou</a> <a href="http://kilobug.free.fr/dice2/" onclick="javascript:urchinTracker ('/outbound/article/kilobug.free.fr');">outra</a> opção, o resto se resume a programas em <a href="http://uncyclopedia.org/wiki/Visual_Basic" onclick="javascript:urchinTracker ('/outbound/article/uncyclopedia.org');">VB</a> que permitem apenas rolagens de dados triviais. Afinal, são poucos os idiotas que, como eu, perdem tempo com esse tipo de coisa! <img src='http://blog.danielfmartins.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p>Eu aproveitei a oportunidade para tornar aquele meu pequeno protótipo &#8212; cujo propósito era mostrar algumas features de <a href="http://groovy.codehaus.org/Dynamic+Groovy" onclick="javascript:urchinTracker ('/outbound/article/groovy.codehaus.org');">meta-programação</a> do Groovy e nada mais &#8212; numa API completa. Por isso, eu optei por dar uma melhorada no código e liberá-lo como sendo um projeto de <em>software</em> livre, que batizei de <a href="http://groovydice.sourceforge.net" onclick="javascript:urchinTracker ('/outbound/article/groovydice.sourceforge.net');">Groovy Dice</a>.</p>
<p class='aligncenter'>
<img src='http://blog.danielfmartins.com/wp-content/uploads/2008/01/logo.png' alt='Groovy Dice' />
</p>
<p>E sim, o site está todo em Inglês, mas há uma boa razão para isso. Uma coisa que me chamou a atenção foi que o <em>post</em> que deu origem a esse projeto foi mais bem recebido por pessoas que não falam Português. Como meu objetivo também é divulgar um pouco do que se pode fazer com o Groovy, então nada melhor do que documentar o projeto em Inglês.</p>
<p>Mas continuando, apesar de ser um projeto bastante simples, ainda existem algumas coisas que eu gostaria de fazer. Uma delas seria prover uma forma para que o usuário possa modificar/estender a API padrão ou até mesmo mudar o &#8220;idioma&#8221; da linguagem:</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="nu0">7</span>.<span class="me1">d10</span> - <span class="nu0">1</span>.<span class="me1">em_cada_dado</span></div>
</li>
</ol>
</div>
<p>Quem quiser dar uma olhada no código-fonte do projeto ou conferir o que já pode ser feito com ele, uma visita <a href="http://groovydice.sourceforge.net" onclick="javascript:urchinTracker ('/outbound/article/groovydice.sourceforge.net');">ao site</a> com certeza será útil. Qualquer contribuição &#8212; seja em forma de código ou comentários &#8212; é mais que bem-vinda.</p>
<p><a name="eng"></a></p>
<h3>For english readers</h3>
<p>In my <a href="http://blog.danielfmartins.com/2007/12/17/dsl-rolando-dados-com-o-groovy/" >previous post</a>, I&#8217;ve shared some thoughts about writing a simple DSL in Groovy to roll dice, but I never thought I&#8217;d receive such feedback from people outside Brazil (probably it&#8217;s <a href="http://groovyblogs.org" onclick="javascript:urchinTracker ('/outbound/article/groovyblogs.org');">GroovyBlogs</a>&#8216; fault). <img src='http://blog.danielfmartins.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> Needless to say that this blog is targeted to portuguese-speaking developers, but I felt the need to take the whole thing to the next level anyway. So, after several improvements on the previously published code, I&#8217;ve released it as a brand new open source project called <a href="http://groovydice.sourceforge.net" onclick="javascript:urchinTracker ('/outbound/article/groovydice.sourceforge.net');">Groovy Dice</a>. But I want you to know my intent, which is to show the people the power of Groovy, hasn&#8217;t changed a bit.</p>
<p>Although this project is a small piece of software, it&#8217;s not finished yet. I believe the next step is to design and implement some stuff to allow the user to modify/extend the default API. In fact, my plan is to leverage the power of Groovy to turn Groovy Dice into a small but very flexible framework.</p>
<p>If you want to play around with Groovy Dice (or just take a look at the <a href="http://sourceforge.net/svn/?group_id=213311" onclick="javascript:urchinTracker ('/outbound/article/sourceforge.net');">source code</a>), please, be my guest! Further instructions on how to <a href="http://groovydice.sourceforge.net/download.html" onclick="javascript:urchinTracker ('/outbound/article/groovydice.sourceforge.net');">download</a>, <a href="http://groovydice.sourceforge.net/integration/index.html" onclick="javascript:urchinTracker ('/outbound/article/groovydice.sourceforge.net');">configure</a> and <a href="http://groovydice.sourceforge.net/features/index.html" onclick="javascript:urchinTracker ('/outbound/article/groovydice.sourceforge.net');">use</a> the API can be found at the <a href="http://groovydice.sourceforge.net" onclick="javascript:urchinTracker ('/outbound/article/groovydice.sourceforge.net');">project&#8217;s website</a>. Any kind of contribution is appreciated.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.danielfmartins.com/2008/01/07/mais-um/feed/</wfw:commentRss>
		</item>
		<item>
		<title>DSL: Rolando dados com o Groovy</title>
		<link>http://blog.danielfmartins.com/2007/12/17/dsl-rolando-dados-com-o-groovy/</link>
		<comments>http://blog.danielfmartins.com/2007/12/17/dsl-rolando-dados-com-o-groovy/#comments</comments>
		<pubDate>Mon, 17 Dec 2007 15:10:16 +0000</pubDate>
		<dc:creator>Daniel F. Martins</dc:creator>
		
		<category><![CDATA[programação]]></category>

		<category><![CDATA[dados]]></category>

		<category><![CDATA[dsl]]></category>

		<category><![CDATA[evento]]></category>

		<category><![CDATA[exemplo]]></category>

		<category><![CDATA[groovy]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[meta programação]]></category>

		<category><![CDATA[rails]]></category>

		<category><![CDATA[rpg]]></category>

		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://blog.danielfmartins.com/2007/12/17/dsl-rolando-dados-com-o-groovy/</guid>
		<description><![CDATA[Provavelmente, muitos dos que acompanham este blog também acompanharam o evento Rails for Kids, que rolou no último sábado. Eu particularmente achei o evento muito bacana, principalmente agora que já terminei de ler o livro Agile Web Development with Rails e estou começando a levar o Rails mais a sério como opção de framework para [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright" src='http://blog.danielfmartins.com/wp-content/uploads/2007/12/212745766_0fe2c4f4d9_m.jpg' alt='Dados de RPG' />Provavelmente, muitos dos que acompanham este <em>blog</em> também acompanharam o evento <a href="http://www.egenial.com.br/railsforkids" onclick="javascript:urchinTracker ('/outbound/article/www.egenial.com.br');">Rails for Kids</a>, que rolou no último sábado. Eu particularmente achei o evento muito bacana, principalmente agora que já terminei de ler o livro <a href="http://pragprog.com/titles/rails2/" onclick="javascript:urchinTracker ('/outbound/article/pragprog.com');">Agile Web Development with Rails</a> e estou começando a levar o <a href="http://rubyonrails.org/" onclick="javascript:urchinTracker ('/outbound/article/rubyonrails.org');">Rails</a> mais a sério como opção de <em>framework</em> para criação de aplicações web. Mas não é sobre isso que falarei hoje.</p>
<p>Apesar de já ter lido um punhado de artigos e <em>posts</em> sobre <a href="http://en.wikipedia.org/wiki/Domain-specific_programming_language" onclick="javascript:urchinTracker ('/outbound/article/en.wikipedia.org');"><acronym title="Domain Specific Language">DSL</acronym>s</a>, a palestra que o <a href="http://logbr.reflectivesurface.com/" onclick="javascript:urchinTracker ('/outbound/article/logbr.reflectivesurface.com');">Ronaldo Ferraz</a> ministrou nesse evento foi o incentivo de que precisava para tomar vergonha na cara e tentar implementar minha primeira DSL. Eu peguei um dos primeiros exemplos que ele citou em sua palestra &#8212; um rolador de dados &#8212; e tentei implementar para ver como ficava. O resultado dessa experiência será detalhado ao longo deste <em>post</em>. </p>
<h3>Sobre a DSL</h3>
<p>A idéia era criar uma DSL em <a href="http://groovy.codehaus.org/" onclick="javascript:urchinTracker ('/outbound/article/groovy.codehaus.org');">Groovy</a> que permitisse especificar rolagens de dados de <acronym title="Role-Playing Game">RPG</acronym> numa &#8220;linguagem&#8221; semelhante à forma que os próprios jogadores costumam usar. Claro que eu adicionei algumas firulas, mas os exemplos abaixo ilustram bem essa &#8220;linguagem&#8221;:</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="nu0">2</span>.<span class="me1">d10</span> + <span class="nu0">5</span>.<span class="me1">d20</span></div>
</li>
<li class="li1">
<div class="de1"><span class="nu0">5</span>.<span class="me1">d</span> - <span class="nu0">2</span>.<span class="me1">d12</span></div>
</li>
<li class="li1">
<div class="de1"><span class="nu0">2</span>.<span class="me1">d20</span> - <span class="nu0">5</span></div>
</li>
<li class="li1">
<div class="de1"><span class="nu0">4</span>.<span class="me1">d</span> * <span class="nu0">4</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#40;</span><span class="nu0">5</span>.<span class="me1">d6</span> + <span class="nu0">5</span><span class="br0">&#41;</span> * <span class="nu0">4</span></div>
</li>
<li class="li1">
<div class="de1"><span class="nu0">5</span>.<span class="me1">d6</span> + <span class="nu0">5</span> * <span class="nu0">4</span></div>
</li>
</ol>
</div>
<p>Cada uma das linhas acima pode ser traduzida para as formas textuais correspondentes:</p>
<ol>
<li>Role 2 dados de 10 faces e 5 dados de 20 faces, e junte os resultados;</li>
<li>Role 5 dados comuns (de 6 faces) e tire dos resultados todos os números sorteados ao rolar 2 dados de 12 faces;</li>
<li>Role 2 dados de 20 faces e adicione um &#8220;-5&#8243; nos resultados;</li>
<li>Role 4 dados de 6 faces e multiplique cada número sorteado por &#8220;+4&#8243;;</li>
<li>Role 5 dados de 6 faces, adicione um &#8220;+5&#8243; nos resultados e multiplique cada número por &#8220;+4&#8243;;</li>
<li>Role 5 dados de 6 faces e adicione nos resultados o retorno da multiplicação de 5 por 4.</li>
</ol>
<p>E não parei por aí; além de permitir a simples rolagem de dados, a DSL também devia fornecer algumas formas de se obter informações sobre um determinado conjunto de resultados. Por exemplo:</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="nu0">10</span>.<span class="me1">d20</span>.<span class="me1">highest</span></div>
</li>
<li class="li1">
<div class="de1"><span class="nu0">5</span>.<span class="me1">d10</span>.<span class="me1">lowest</span>.<span class="me1">d6</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#40;</span><span class="nu0">6</span>.<span class="me1">d12</span> - <span class="nu0">2</span><span class="br0">&#41;</span>.<span class="me1">sum</span></div>
</li>
<li class="li1">
<div class="de1"><span class="nu0">5</span>.<span class="me1">d20</span>.<span class="me1">average</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#40;</span><span class="nu0">2</span>.<span class="me1">d10</span> + <span class="nu0">6</span>.<span class="me1">d</span><span class="br0">&#41;</span>.<span class="me1">best</span><span class="br0">&#40;</span><span class="nu0">3</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#40;</span><span class="nu0">2</span>.<span class="me1">d10</span> + <span class="nu0">6</span>.<span class="me1">d</span><span class="br0">&#41;</span>.<span class="me1">worst</span><span class="br0">&#40;</span><span class="nu0">3</span><span class="br0">&#41;</span></div>
</li>
</ol>
</div>
<p>Novamente, cada uma das linhas acima podem ser traduzidas para:</p>
<ol>
<li>Role 10 dados de 20 faces e retorne o maior número que foi sorteado;</li>
<li>Role 5 dados de 10 faces, pegue o menor número que foi sorteado e role dados de 6 faces por esse número de vezes;</li>
<li>Role 6 dados de 12 faces, adicione um &#8220;-2&#8243; e retorne a soma dos resultados;</li>
<li>Role 5 dados de 20 faces e retorne a média dos números sorteados;</li>
<li>Role 2 dados de 10 faces e 6 dados de 6 faces, e retorne os 3 melhores números sorteados;</li>
<li>Role 2 dados de 10 faces e 6 dados de 6 faces, e retorne os 3 piores números sorteados.</li>
</ol>
<p>Uma das características mais marcantes em DSLs bem projetadas é que tais linguagens podem ser facilmente entendidas por especialistas do domínio, mesmo se tais especialistas não tiverem nenhum conhecimento em programação.</p>
<p>Para ilustrar essa afirmação, podemos dizer sem medo de errar que uma instrução Groovy <code>new DiceRollingSpec(sides:4).roll(5)</code> pode não significar absolutamente nada para a maioria dos jogadores de RPG. Entretanto, se você já jogou RPG alguma vez na vida, sabe que uma instrução <code>5.d4</code> é facilmente entendida por qualquer jogador.</p>
<p>Preparado para o código? Então vamos nessa. <img src='http://blog.danielfmartins.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>Primeiro: resolvendo o problema&#8230; a qualquer custo</h3>
<p>Antes de enveredarmos na criação da DSL, precisamos criar código que nos forneça a funcionalidade necessária, que é <strong>rolar dados</strong> e colher informações sobre os mesmos.</p>
<p>Como o código é extremamente simples, não precisarei ficar explicando. Basta conhecer o básico da linguagem Groovy para entender. Veja só:</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20class" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">class</span></a> DiceRollingSpec <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20int" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw4">int</span></a> sides = <span class="nu0">6</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20def" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">def</span></a> result = <span class="br0">&#91;</span><span class="br0">&#93;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20def" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">def</span></a> roll<span class="br0">&#40;</span>n=<span class="nu0">1</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; n.<a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20times" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw8">times</span></a> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20&amp;lt;" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw1">&lt;&lt;</span></a> <span class="br0">&#40;</span><a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20int" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw4">int</span></a><span class="br0">&#41;</span> <span class="br0">&#40;</span><a href="http://www.google.de/search?as_q=Math&#038;num=100&#038;hl=en&#038;as_occt=url&#038;as_sitesearch=java.sun.com%2Fj2se%2F1.5.0%2Fdocs%2Fapi%2F" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw3">Math</span></a>.<span class="me1">random</span><span class="br0">&#40;</span><span class="br0">&#41;</span> * sides<span class="br0">&#41;</span> + <span class="nu0">1</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20this" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">this</span></a></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20def" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">def</span></a> getSum<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; result.<span class="me1">sum</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20def" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">def</span></a> getHighest<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; result.<a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20max" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw5">max</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20def" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">def</span></a> getLowest<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; result.<a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20min" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw5">min</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20def" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">def</span></a> getAverage<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20int" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw4">int</span></a><span class="br0">&#41;</span> <span class="br0">&#40;</span>result.<span class="me1">sum</span><span class="br0">&#40;</span><span class="br0">&#41;</span> / result.<a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20size" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw5">size</span></a><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20def" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">def</span></a> best<span class="br0">&#40;</span>n=<span class="nu0">1</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; n = n &gt; <span class="nu0">0</span> ? n : <span class="nu0">1</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; result.<a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20sort" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw5">sort</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span>.<a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20reverse" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw5">reverse</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#91;</span>n == <span class="nu0">1</span> ? <span class="nu0">0</span> : <span class="br0">&#40;</span><span class="nu0">0</span>..<span class="me1"><span class="br0">&#40;</span>n</span><span class="nu0">-1</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#93;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20def" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">def</span></a> worst<span class="br0">&#40;</span>n=<span class="nu0">1</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; n = n &gt; <span class="nu0">0</span> ? n : <span class="nu0">1</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; result.<a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20sort" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw5">sort</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#91;</span>n == <span class="nu0">1</span> ? <span class="nu0">0</span> : <span class="br0">&#40;</span><span class="nu0">0</span>..<span class="me1"><span class="br0">&#40;</span>n</span><span class="nu0">-1</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#93;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20def" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">def</span></a> plus<span class="br0">&#40;</span>value<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20if" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw1">if</span></a> <span class="br0">&#40;</span>value <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20instanceof" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">instanceof</span></a> <a href="http://www.google.de/search?as_q=Integer&#038;num=100&#038;hl=en&#038;as_occt=url&#038;as_sitesearch=java.sun.com%2Fj2se%2F1.5.0%2Fdocs%2Fapi%2F" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw3">Integer</span></a><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20return" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">return</span></a> <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20new" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">new</span></a> DiceRollingSpec<span class="br0">&#40;</span>sides:sides,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result:result.<a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20collect" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw5">collect</span></a><span class="br0">&#123;</span>it<span class="br0">&#125;</span> + value<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20else" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw1">else</span></a> <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20if" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw1">if</span></a> <span class="br0">&#40;</span>value <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20instanceof" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">instanceof</span></a> DiceRollingSpec<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20return" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">return</span></a> <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20new" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">new</span></a> DiceRollingSpec<span class="br0">&#40;</span>sides:sides &gt; value.<span class="me1">sides</span> ? sides : value.<span class="me1">sides</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result:result + value.<span class="me1">result</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20throw" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">throw</span></a> <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20new" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">new</span></a> <a href="http://www.google.de/search?as_q=IllegalArgumentException&#038;num=100&#038;hl=en&#038;as_occt=url&#038;as_sitesearch=java.sun.com%2Fj2se%2F1.5.0%2Fdocs%2Fapi%2F" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw3">IllegalArgumentException</span></a><span class="br0">&#40;</span><span class="st0">&quot;Invalid argument: $value&quot;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20def" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">def</span></a> minus<span class="br0">&#40;</span>value<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20if" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw1">if</span></a> <span class="br0">&#40;</span>value <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20instanceof" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">instanceof</span></a> <a href="http://www.google.de/search?as_q=Integer&#038;num=100&#038;hl=en&#038;as_occt=url&#038;as_sitesearch=java.sun.com%2Fj2se%2F1.5.0%2Fdocs%2Fapi%2F" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw3">Integer</span></a><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20return" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">return</span></a> plus<span class="br0">&#40;</span>-value<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20else" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw1">else</span></a> <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20if" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw1">if</span></a> <span class="br0">&#40;</span>value <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20instanceof" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">instanceof</span></a> DiceRollingSpec<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20return" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">return</span></a> <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20new" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">new</span></a> DiceRollingSpec<span class="br0">&#40;</span>sides:sides, result:result - value.<span class="me1">result</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20throw" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">throw</span></a> <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20new" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">new</span></a> <a href="http://www.google.de/search?as_q=IllegalArgumentException&#038;num=100&#038;hl=en&#038;as_occt=url&#038;as_sitesearch=java.sun.com%2Fj2se%2F1.5.0%2Fdocs%2Fapi%2F" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw3">IllegalArgumentException</span></a><span class="br0">&#40;</span><span class="st0">&quot;Invalid argument: $value&quot;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20def" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">def</span></a> multiply<span class="br0">&#40;</span>value<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20if" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw1">if</span></a> <span class="br0">&#40;</span>value <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20instanceof" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">instanceof</span></a> <a href="http://www.google.de/search?as_q=Integer&#038;num=100&#038;hl=en&#038;as_occt=url&#038;as_sitesearch=java.sun.com%2Fj2se%2F1.5.0%2Fdocs%2Fapi%2F" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw3">Integer</span></a><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20return" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">return</span></a> <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20new" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">new</span></a> DiceRollingSpec<span class="br0">&#40;</span>sides:sides,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result:result.<a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20collect" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw5">collect</span></a><span class="br0">&#123;</span>it * value<span class="br0">&#125;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20throw" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">throw</span></a> <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20new" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">new</span></a> <a href="http://www.google.de/search?as_q=IllegalArgumentException&#038;num=100&#038;hl=en&#038;as_occt=url&#038;as_sitesearch=java.sun.com%2Fj2se%2F1.5.0%2Fdocs%2Fapi%2F" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw3">IllegalArgumentException</span></a><span class="br0">&#40;</span><span class="st0">&quot;Invalid argument: $value&quot;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>Com exceção dos três últimos métodos, o resto é extremamente simples de entender. Na verdade, os três últimos métodos sobrescrevem os operadores <code>+</code>, <code>-</code> e <code>*</code> para objetos <code>DiceRollingSpec</code>. Isso permite que objetos dessa classe sejam usados em alguns tipos de expressões como as citadas anteriormente. Um exemplo de expressão válida:</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20new" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">new</span></a> DiceRollingSpec<span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">roll</span><span class="br0">&#40;</span><span class="nu0">4</span><span class="br0">&#41;</span> + <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20new" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">new</span></a> DiceRollingSpec<span class="br0">&#40;</span>sides:<span class="nu0">10</span><span class="br0">&#41;</span>.<span class="me1">roll</span><span class="br0">&#40;</span><span class="nu0">7</span><span class="br0">&#41;</span> <span class="co1">// 4.d + 7.d10</span></div>
</li>
</ol>
</div>
<p>No entanto, esse código não possui a expressividade que gostaríamos de ver numa <acronym title="Application Programming Interface">API</acronym> de rolagem de dados.</p>
<h3>Segundo: adicionando expressividade à solução</h3>
<p>Como vimos, o ponto de partida para se especificar rolagens de dados se parece com o seguinte:</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">I.<span class="me1">dX</span></div>
</li>
</ol>
</div>
<p><code>I</code> é um objeto <code>Integer</code> qualquer e indica o número de vezes que o dado deve ser lançado; <code>dX</code> indica o tipo de dado, que é codificado como sendo um método <em>getter</em> <code>getDX()</code>, onde <code>X</code> é o número de faces do dado.</p>
<p>Agora, qual a razão de eu ter escolhido usar um método <em>getter</em> a um método comum? Veja só o exemplo abaixo:</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="nu0">5</span>.<span class="me1">d12</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
</ol>
</div>
<p>Infelizmente, o Groovy <strong>exige</strong> a digitação do &#8220;abre-e-fecha-parênteses&#8221; ao invocar métodos sem parâmetros. Como a idéia era representar o mais fielmente possível a forma com que jogadores de RPG especificam rolagens de dados, esse &#8220;abre-e-fecha-parênteses&#8221; acaba sujando o código e prejudicando sua expressividade; eu particularmente nunca vi alguém dizer &#8220;beleza, agora eu vou rolar cinco dê-doze abre-e-fecha-parênteses&#8230; esse monstro vai ver só uma coisa!&#8221;. <img src='http://blog.danielfmartins.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p>Mas beleza&#8230; agora que sabemos como deverá funcionar, precisamos arranjar um jeito de retornar objetos <code>DiceRollingSpec</code> sempre que <em>getters</em> <code>getDX()</code> forem invocados em objetos <code>Integer</code>. Felizmente, o Groovy fornece uma forma bem fácil de se fazer isso:</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><a href="http://www.google.de/search?as_q=Integer&#038;num=100&#038;hl=en&#038;as_occt=url&#038;as_sitesearch=java.sun.com%2Fj2se%2F1.5.0%2Fdocs%2Fapi%2F" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw3">Integer</span></a>.<span class="me1">metaClass</span>.<span class="me1">propertyMissing</span> = <span class="br0">&#123;</span> name -&gt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20if" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw1">if</span></a> <span class="br0">&#40;</span>name == <span class="st0">&#8216;d&#8217;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; name = <span class="st0">&#8216;d6&#8242;</span> <span class="co1">// 6-sided dice is the default dice type</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="coMULTI">/* intercept calls to &#8216;dX&#8217; properties */</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20if" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw1">if</span></a> <span class="br0">&#40;</span>name =~ /^d\d+$/<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20return" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">return</span></a> <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20new" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">new</span></a> DiceRollingSpec<span class="br0">&#40;</span>sides:<a href="http://www.google.de/search?as_q=Integer&#038;num=100&#038;hl=en&#038;as_occt=url&#038;as_sitesearch=java.sun.com%2Fj2se%2F1.5.0%2Fdocs%2Fapi%2F" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw3">Integer</span></a>.<span class="me1">parseInt</span><span class="br0">&#40;</span>name.<span class="me1">substring</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .<span class="me1">roll</span><span class="br0">&#40;</span>value<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20throw" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">throw</span></a> <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20new" onclick="javascript:urchinTracker ('/outbound/article/www.google.de');"><span class="kw2">new</span></a> MissingPropertyException<span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;No such property: $name for class: ${value.class}&quot;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>O Groovy fornece diversas soluções para modificar objetos e classes em <em>runtime</em>; a que parece mais adequada ao nosso problema é interceptar chamadas a <em>getters</em> <code>getDX()</code> e retor