<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>DestaqueBlog &#187; design</title>
	<atom:link href="http://weblog.destaquenet.com/tag/design/feed/" rel="self" type="application/rss+xml" />
	<link>http://weblog.destaquenet.com</link>
	<description>Blog da equipe Destaquenet.</description>
	<lastBuildDate>Tue, 23 Nov 2010 17:06:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Django e settings.py: dicas e boas práticas</title>
		<link>http://weblog.destaquenet.com/2009/04/13/django-e-settingspy-dicas-e-boas-praticas/</link>
		<comments>http://weblog.destaquenet.com/2009/04/13/django-e-settingspy-dicas-e-boas-praticas/#comments</comments>
		<pubDate>Tue, 14 Apr 2009 01:32:06 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Português]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[boas práticas]]></category>
		<category><![CDATA[configuração]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[testes]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=415</guid>
		<description><![CDATA[Em vez de ficar rasgando elogios ao Django, como de costume, eu tentarei aproveitar o melhor o meu (e o seu) tempo e mostrar algo que é de fato útil. O assunto em questão envolve o módulo settings.py, cuja função &#8230; <a href="http://weblog.destaquenet.com/2009/04/13/django-e-settingspy-dicas-e-boas-praticas/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Em vez de ficar rasgando elogios ao <a href="http://djangoproject.com">Django</a>, como de costume, eu tentarei aproveitar o melhor o meu (e o seu) tempo e mostrar algo que é de fato útil. O assunto em questão envolve o módulo <code>settings.py</code>, cuja função é fornecer as configurações necessárias para que o projeto funcione. Apesar deste módulo ser uma peça importante em qualquer projeto Django, pouco se fala sobre ele, ou sobre boas práticas associadas a ele. Por isso, achei que seria interessante mostrar a minha visão pessoal sobre o assunto.</p>
<h3>O poder do Python</h3>
<p>Quem não está acostumado a trabalhar com Django pode estranhar o fato deste utilizar um script <a href="http://python.org">Python</a> para fazer a configuração do projeto: o famoso <code>settings.py</code>. E essa estranheza é justificada, afinal muitos desenvolvedores &#8212; principalmente os que vêm de outras linguagens &#8212; estão acostumados a trabalhar com ferramentas onde tal tarefa é feita com arquivos XML ou coisa assim.</p>
<p>O fato é que utilizar um script Python para tal é uma excelente idéia, pois você deixa de depender de algum tipo de estrutura estática (e muitas vezes inconveniente) para algo mais flexível e poderoso, que, no caso, é a própria linguagem de programação. Isso faz uma grande diferença em situações onde tal flexibilidade é necessária.</p>
<p>Quer exemplos?<span id="more-415"></span></p>
<h3>Ambientes de desenvolvimento/produção</h3>
<p>Eis como fizemos aqui. Primeiramente, defina a variável de ambiente <code>WORKSPACE</code>. No Linux, isso pode ser feito através do arquivo <code>~/.bashrc</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">WORKSPACE</span>=<span style="color: #000000;">1</span></pre></div></div>

<p>A idéia é possibilitar a criação de perfis de configuração, cada qual correspondente a um ambiente de execução. A existência ou não da variável de ambiente é o que define o ambiente no qual a aplicação roda.</p>
<p>Continuando com o exemplo, no diretório raíz do seu projeto Django, crie o módulo <code>environment.py</code>, com o seguinte conteúdo:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> production_mode<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #ff7700;font-weight:bold;">not</span> development_mode<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> development_mode<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">'WORKSPACE'</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">environ</span></pre></div></div>

<p>Finalmente, modifique o módulo <code>settings.py</code> para que este utilize tais métodos onde for necessário definir configurações diferentes para ambientes de execução diferentes:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> environment <span style="color: #ff7700;font-weight:bold;">import</span> production_mode
&nbsp;
<span style="color: #808080; font-style: italic;"># Configurações padrão</span>
PREPEND_WWW = <span style="color: #008000;">False</span>
DEBUG = <span style="color: #008000;">True</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Configurações para ambiente de produção</span>
<span style="color: #ff7700;font-weight:bold;">if</span> production_mode<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    PREPEND_WWW = <span style="color: #008000;">True</span>
    DEBUG = <span style="color: #008000;">False</span>
&nbsp;
MIDDLEWARE_CLASSES = <span style="color: black;">&#40;</span>
    <span style="color: #483d8b;">'django.middleware.common.CommonMiddleware'</span>,
    <span style="color: #483d8b;">'django.contrib.sessions.middleware.SessionMiddleware'</span>,
    <span style="color: #483d8b;">'django.contrib.auth.middleware.AuthenticationMiddleware'</span>,
    <span style="color: #483d8b;">'django.middleware.doc.XViewMiddleware'</span>,
    <span style="color: #483d8b;">'pages.middleware.PageFallbackMiddleware'</span>,
    <span style="color: #483d8b;">'django.contrib.redirects.middleware.RedirectFallbackMiddleware'</span>,
<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Habilitando caching em modo de produção</span>
<span style="color: #ff7700;font-weight:bold;">if</span> production_mode<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    MIDDLEWARE_CLASSES += <span style="color: black;">&#40;</span>
        <span style="color: #483d8b;">'django.middleware.cache.UpdateCacheMiddleware'</span>,
        <span style="color: #483d8b;">'django.middleware.cache.FetchFromCacheMiddleware'</span>,
    <span style="color: black;">&#41;</span></pre></div></div>

<p>Não tenha medo de utilizar os recursos do Python onde eles se fizerem necessários, apenas tomando cuidado para não exagerar e acabar criando acidentalmente um <a href="http://en.wikipedia.org/wiki/Genetic_algorithm">Algoritmo Genético</a> para configurar seu projeto!</p>
<h3>Informações secretas (IPs, usernames, passwords, etc)</h3>
<p>Praticamente não há quem ignore a importância de um bom sistema de controle de revisões (<a href="http://subversion.tigris.org">Subversion</a>, <a href="http://git-scm.org">Git</a>, etc). O problema é que, muitas vezes, não tomamos o devido cuidado com o que colocamos dentro dos nossos repositórios. Sempre que possível, informações secretas &#8212; como endereços de IP, usernames e passwords &#8212; devem ser mantidas fora dos repositórios.</p>
<p>Em um projeto Django, as informações de acesso a servidores de e-mail e bancos de dados devem estar disponíveis através do módulo  <code>settings.py</code>. Felizmente, existe um jeito simples de manter essas informações separadas das outras configurações.</p>
<p>Primeiramente, abra o arquivo <code>settings.py</code> do seu projeto e remova todas as senhas e outras informações que você considere secretas. Em seguida, cole o seguinte trecho de código no final do arquivo:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">try</span>:
    <span style="color: #ff7700;font-weight:bold;">from</span> private <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
<span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">ImportError</span>:
    <span style="color: #ff7700;font-weight:bold;">pass</span></pre></div></div>

<p>Feito isso, crie o módulo <code>private.py</code> no diretório raíz do seu projeto Django. Coloque nele as configurações que você removeu do <code>settings.py</code> no passo anterior. Exemplo:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> environment <span style="color: #ff7700;font-weight:bold;">import</span> production_mode
&nbsp;
SECRET_KEY = <span style="color: #483d8b;">'secret_key_do_seu_projeto'</span>
&nbsp;
EMAIL_HOST = <span style="color: #483d8b;">'localhost'</span>
EMAIL_HOST_PASSWORD = <span style="color: #483d8b;">'senha_email_local'</span>
&nbsp;
DATABASE_HOST = <span style="color: #483d8b;">'localhost'</span>
DATABASE_USER = <span style="color: #483d8b;">'username_db_local'</span>
DATABASE_PASSWORD = <span style="color: #483d8b;">'senha_db_local'</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> production_mode<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    EMAIL_HOST = <span style="color: #483d8b;">'ip_email_producao'</span>
    EMAIL_HOST_PASSWORD = <span style="color: #483d8b;">'senha_email_producao'</span>
&nbsp;
    DATABASE_HOST = <span style="color: #483d8b;">'ip_db_producao'</span>
    DATABSE_USER = <span style="color: #483d8b;">'username_db_producao'</span>
    DATABASE_PASSWORD = <span style="color: #483d8b;">'senha_db_producao'</span></pre></div></div>

<p>Certifique-se de adicionar o arquivo <code>private.py</code> no <em>ignore</em> (<code>.cvsignore</code> para <a href="http://www.nongnu.org/cvs/">CVS</a>, <code>.gitignore</code> para Git, etc) correspondente ao sistema de controle de revisões sendo utilizado. Faça o commit e pronto.</p>
<p>Para finalizar, se o seu repositório já contém uma versão &#8220;insegura&#8221; do módulo <code>settings.py</code>, mude as senhas dos seus servidores.</p>
<h3>E você, o que recomenda?</h3>
<p>Tem alguma dica útil para compartilhar conosco? Nós adoraríamos ouvir o que você tem a dizer!</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2009/04/13/django-e-settingspy-dicas-e-boas-praticas/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Por favor, usem typesafe enums!</title>
		<link>http://weblog.destaquenet.com/2009/02/18/por-favor-usem-typesafe-enums/</link>
		<comments>http://weblog.destaquenet.com/2009/02/18/por-favor-usem-typesafe-enums/#comments</comments>
		<pubDate>Thu, 19 Feb 2009 02:20:35 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Português]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[análise]]></category>
		<category><![CDATA[banco de dados]]></category>
		<category><![CDATA[boas práticas]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[enums]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[modelagem]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=349</guid>
		<description><![CDATA[Enquanto conversava com um amigo, há alguns dias atrás, surgiu um assunto a respeito de algo que costumamos ver com certa frequência. Vou tentar contextualizar essa conversa com o diagrama UML Entidade-Relacionamento a seguir: Nem irei perder tempo explicando esse &#8230; <a href="http://weblog.destaquenet.com/2009/02/18/por-favor-usem-typesafe-enums/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Enquanto conversava com um amigo, há alguns dias atrás, surgiu um assunto a respeito de algo que costumamos ver com certa frequência. Vou tentar contextualizar essa conversa com o diagrama <span style="text-decoration: line-through;">UML</span> Entidade-Relacionamento a seguir:</p>
<div id="attachment_358" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2009/02/diagram01.png"><img class="size-medium wp-image-358" title="Diagrama" src="http://weblog.destaquenet.com/wp-content/uploads/2009/02/diagram01-300x218.png" alt="Modelo-exemplo de banco de dados" width="300" height="218" /></a><p class="wp-caption-text">Modelo-exemplo de banco de dados</p></div>
<p>Nem irei perder tempo explicando esse modelo, até porque não há nada nele que precise de explicações. Bem, na verdade, há uma coisa sim: <strong>por que raios existe uma tabela só para armazenar os tipos de contato?!</strong> Qual é o problema com os bons e velhos códigos fixos (1-email, 2-celular, N-&#8230;)?</p>
<p>Um argumento a favor dessa abordagem é que &#8220;o usuário pode querer cadastrar um contato cujo tipo não seja suportado pela aplicação&#8221;. Mas será mesmo que colocar essa informação no banco de dados resolve o problema? E, mais importante, existe algum efeito colateral?</p>
<p>Bem, na minha experiência, embora essa abordagem pareça boa o bastante para resolver a questão num sistema simples de &#8220;cadastro&#8221;, a bomba explode quando o sistema passa a depender dessas flags para a realização de lógicas de negócio que vão além do famigerado CRUD. <span id="more-349"></span></p>
<h3>Anti-pattern?</h3>
<p>E se eu te dissesse que usar tabelas no banco de dados para armazenar flags é um anti-pattern? Digo isso pois, como veremos a seguir, as vantagens são irrisórias frente às desvantagens:</p>
<p><strong>Poluição do modelo de dados.</strong> Um sistema não muito grande provavelmente conta com mais de uma centena de tabelas. Isso todo mundo sabe. O que todo mundo também sabe, mas parece ignorar, é que não seria surpreendente constatar que 10-15% dessas tabelas serviriam apenas para armazenar flags (situação de pedido, estado civil, forma de pagamento, e por aí vai). E o pior: essas tabelas, quase sempre, possuem exatamente a mesma estrutura, que apelidei carinhosamente de <strong>tabelas código-descrição</strong>. A tabela <code>TipoContato</code>, mostrada no diagrama que encabeça este texto, é um exemplo desse tipo de tabela.</p>
<p><strong>Ruim para o meio ambiente.</strong> Poluir o modelo de dados com dezenas de <strong>tabelas código-descrição</strong> torna o modelo desnecessariamente maior e mais difícil de compreender. Imprimir um modelo desses consome mais papel, o que é ruim numa época onde o desenvolvimento sustentável está em voga. Quantas árvores suas <strong>tabelas código-descrição</strong> já derrubaram?</p>
<p><strong>Ultra-normalização.</strong> Quanto mais tabelas uma consulta envolver, mais joins, e mais dados indo e vindo para o banco de dados. E, considerando que o banco de dados é (quase) sempre o gargalo, isso não é muito bom para a performance do seu sistema.</p>
<p><strong>Poluição do modelo de objetos.</strong> As linguagens com suporte à orientação a objetos figuram entre as <a href="http://www.tiobe.com/content/paperinfo/tpci/index.html">mais usadas atualmente</a>, por isso eu diria que muito provavelmente você utiliza esse paradigma no desenvolvimento dos seus sistemas. Se este for o caso, também é bem provável que você utilize algum framework ORM para facilitar a tarefa de integração do software com o banco de dados. Como muitos frameworks ORM exigem um modelo de objetos compatível com o modelo de dados, bem, você acaba sendo forçado a poluir seu modelo de objetos com classes burras que apelidei carinhosamente de (pasmem!) <strong>classes código-descrição</strong>.</p>
<p><strong>Se tem tabela, tem cadastro.</strong> Bom, já que todas as flags possuem suas tabelinhas no banco de dados, isso significa que você, pobre desenvolvedor, terá que fazer &#8220;cadastros&#8221; para todas elas (e reze para não precisar fazer relatórios, também). Além da chatisse costumeira de se fazer um cadastro, devemos levar em consideração que fazê-los consome tempo e, tempo é dinheiro.</p>
<p><strong>Código quebradiço.</strong> Essa é feia. Vamos supor que, nessa nossa aplicação de gerenciamento de clientes/contatos, você queira incluir uma funcionalidade que permita enviar um torpedo ao cliente caso ele possua um contato do tipo <code>Celular</code>. Como mostrado no trecho de código a seguir, você fatalmente terá que incluir no código-fonte referências a registros armazenados no banco de dados, tornando o código quebradiço. Consequentemente, um único <code>UPDATE</code> ou <code>DELETE</code> executado por engano no banco de dados pode fazer o sistema cair de joelhos.</p>
<p>Enviando torpedos a um cliente:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> enviarTorpedo<span style="color: #009900;">&#40;</span>Cliente cliente, <span style="color: #003399;">String</span> texto<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Tenta localizar um contato do tipo celular</span>
    <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>Contato contato <span style="color: #339933;">:</span> cliente.<span style="color: #006633;">getContatos</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
         <span style="color: #666666; font-style: italic;">// WTF!! Estamos referenciando um registro do banco de dados!!</span>
         <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>contato.<span style="color: #006633;">getCodigo</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> 10L<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            SMSUtil.<span style="color: #006633;">enviarTorpedo</span><span style="color: #009900;">&#40;</span>contato.<span style="color: #006633;">getValor</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, texto<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h3>A solução</h3>
<p>Com certeza existem outros problemas que eu acabei deixando passar, mas espero que os problemas que listei já sejam o suficiente para te convencer que guardar flags em tabelas no banco de dados é uma má idéia.</p>
<p>Mas, como resolver isso então? Simples: <strong>use enums sempre que possível.</strong> A única desvantagem é que os usuários não poderão mais sair criando novas flags a torto e a direito, o que não é realmente um problema frente às vantagens que as enums oferecem<strong>.<br />
</strong></p>
<p><strong>Poluição do modelo de dados?</strong> As flags virariam campos numéricos ou alfanuméricos nas tabelas que as usam e o framework ORM se encarregaria de converter esses campos de/para objetos enum. Diga adeus às <strong>tabelas código-descrição</strong>.</p>
<p><strong>Ruim para o meio-ambiente?</strong> Sem as <strong>tabelas código-descrição</strong>, seu modelo fica menor, mais enxuto, facilitando a visualização e gastando menos papel ao imprimí-lo. A natureza agradece.</p>
<p><strong>Ultra-normalização?</strong> Usando enums você diminui a quantidade de ligações entre as tabelas, tornando as entidades um pouco mais auto-contidas. Menos tabelas, menos joins, mais performance.</p>
<p><strong>Poluição do modelo de objetos?</strong> As enums tomariam o lugar das <strong>classes código-descrição</strong>, o que por si só tornaria o código mais claro, pois, ao contrário das classes &#8220;normais&#8221;, as enums possuem um propósito bem definido.</p>
<p><strong>Se tem tabela, tem cadastro?</strong> Ué, por que você está com esse sorriso estampado no rosto?</p>
<p><strong>Código quebradiço?</strong> Quem mais se beneficia das enums são os trechos de código onde as lógicas de negócio são definidas. Mais especificamente, seu código deixa de referenciar registros do banco de dados, eliminando a fragilidade e melhorando a legibilidade. As enums também impedem que valores arbitrários sejam usados em atribuições e comparações, tornando o código ainda mais confiável. Um exemplo disso pode ser visto no código a seguir, que é uma adaptação <span style="text-decoration: line-through;">da atrocidade</span> do código mostrado anteriormente:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> enviarTorpedo<span style="color: #009900;">&#40;</span>Cliente cliente, <span style="color: #003399;">String</span> texto<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>Contato contato <span style="color: #339933;">:</span> cliente.<span style="color: #006633;">getContatos</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
         <span style="color: #666666; font-style: italic;">// Bem melhor agora!</span>
         <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>contato.<span style="color: #006633;">getTipo</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> TipoContato.<span style="color: #006633;">CELULAR</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            SMSUtil.<span style="color: #006633;">enviarTorpedo</span><span style="color: #009900;">&#40;</span>contato.<span style="color: #006633;">getValor</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, texto<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>O fato de a sua linguagem do coração não ter suporte nativo a enums não deve ser um impedimento para que você deixe de usufruir de suas vantagens. <a href="http://www.ditchnet.org/wp/2005/05/08/typesafe-enum-pattern-in-python/">Existem formas</a> de se conseguir uma funcionalidade semelhante sem muito esforço.</p>
<h3>Conclusão</h3>
<p>Desenvolver software é, antes de tudo, fazer escolhas. É o custo/benefício, os prós e contras antes de se tomar uma decisão. A boa notícia é que o nosso produto, o software, é maleável o suficiente para permitir que decisões ruins sejam re-feitas sempre que elas resultam em problemas como o descrito neste texto.</p>
<p>Bom carnaval!</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2009/02/18/por-favor-usem-typesafe-enums/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>JavaEE 5 interceptors</title>
		<link>http://weblog.destaquenet.com/2008/09/21/javaee-5-interceptors/</link>
		<comments>http://weblog.destaquenet.com/2008/09/21/javaee-5-interceptors/#comments</comments>
		<pubDate>Sun, 21 Sep 2008 03:30:58 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Português]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[annotations]]></category>
		<category><![CDATA[aop]]></category>
		<category><![CDATA[container]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[ejb]]></category>
		<category><![CDATA[ioc]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[javaee]]></category>
		<category><![CDATA[reflection]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=41</guid>
		<description><![CDATA[É inegável que a não-tão-nova versão 5 da especificação JavaEE veio numa hora mais do que necessária. Todo mundo parecia &#8212; e com razão &#8212; evitá-la ao máximo, pois seu uso demandava muito tempo e caixas de calmante. Hoje, criar &#8230; <a href="http://weblog.destaquenet.com/2008/09/21/javaee-5-interceptors/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>É inegável que a não-tão-nova <a href="http://jcp.org/aboutJava/communityprocess/pfd/jsr244/">versão 5</a> da especificação JavaEE veio numa hora mais do que necessária. Todo mundo parecia &#8212; e com razão &#8212; evitá-la ao máximo, pois seu uso demandava muito tempo e caixas de calmante.</p>
<p>Hoje, criar e manter uma aplicação com <acronym title="Enterprise JavaBeans">EJBs</acronym> é relativamente simples. E, por este motivo, a adoção da tecnologia passou a ser mais expressiva, mesmo em projetos menores.</p>
<p>Alguns aspectos da especificação, entretanto, ainda deixam a desejar. Um exemplo seria a parte de injeção de dependências, que é limitada apenas a componentes gerenciados pelo <em>container</em>. O que isso quer dizer? Isso quer dizer que, para você poder tirar proveito do esquema de injeção de dependências, todos os seus componentes precisam ser EJBs.</p>
<p>Mas, nesta versão, os EJBs não são <acronym title="Plain Old Java Object">POJO</acronym>s? Sim, mas ter de expor classes simples como EJBs &#8212; só para ganhar essa &#8220;injetabilidade&#8221; de presente &#8212; não parece correto. E, da mesma forma, espalhar instanciações de objetos pelos vários componentes da aplicação definitivamente também não parece.<span id="more-41"></span></p>
<p>Por isso, mostrarei a seguir um exemplo de como melhorar a parte de injeção de dependências para que possamos injetar POJOs declarativamente em objetos gerenciados. Como o <a href="http://www.springframework.org/">Spring</a> é (de longe) o <em>framework</em> mais conhecido, eu o usarei para me ajudar nesta tarefa.</p>
<h3>O exemplo</h3>
<p>Para demonstrar o efeito desejado, veja o trecho de código a seguir:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">interface</span> Calculator <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">int</span> mult<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> a, <span style="color: #000066; font-weight: bold;">int</span> b<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> CalculatorImpl <span style="color: #000000; font-weight: bold;">implements</span> Calculator <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">int</span> mult<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> a, <span style="color: #000066; font-weight: bold;">int</span> b<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> a<span style="color: #339933;">*</span>b<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
@<span style="color: #003399;">Remote</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">interface</span> MultiplicationRuler <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> rulerFor<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> number, <span style="color: #000066; font-weight: bold;">int</span> from, <span style="color: #000066; font-weight: bold;">int</span> to<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
@Stateless
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MultiplicationRulerBean <span style="color: #000000; font-weight: bold;">implements</span> MultiplicationRuler <span style="color: #009900;">&#123;</span>
&nbsp;
    @InjectBean
    <span style="color: #000000; font-weight: bold;">private</span> Calculator calculator<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> rulerFor<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> number, <span style="color: #000066; font-weight: bold;">int</span> from, <span style="color: #000066; font-weight: bold;">int</span> to<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">int</span> total <span style="color: #339933;">=</span> to<span style="color: #339933;">-</span>from<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> ruler <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span>total<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> total<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            ruler<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> calculator.<span style="color: #006633;">mult</span><span style="color: #009900;">&#40;</span>number, from<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">return</span> ruler<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>O objetivo aqui é implementar um componente POJO que multiplica dois números. Este componente é usado por um segundo &#8212; este sim um EJB &#8212; que fornece um método que funciona mais ou menos igual aquelas réguas de tabuada; o método recebe o número desejado e dois outros números que representam os limites da tabuada. Por exemplo, a chamada abaixo retorna os resultados da tabuada de 10, começando no número 1 e indo até o 15:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">MultiplicationRulerBean ruler <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MultiplicationRulerBean<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
ruler.<span style="color: #006633;">rulerFor</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">10</span>,<span style="color: #cc66cc;">1</span>,<span style="color: #cc66cc;">15</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Note, na classe <code>MultiplicationRulerBean</code>, que o atributo <code>Calculator</code> está anotado com <code>@InjectBean</code>. Esta anotação servirá para indicar que este campo representa uma dependência que deve ser resolvida injetando-se uma instância de <code>Calculator</code>.</p>
<h3>Usando o Spring para obter dependências</h3>
<p>Segue um exemplo de arquivo de contexto <code>appcontext-services.xml</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;beans<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;bean</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;calculatorBean&quot;</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;CalculatorImpl&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/beans<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Como nossa única dependência externa é uma instância de <code>Calculator</code>, então o arquivo se resume a apenas uma entrada <code>&lt;bean&gt;</code>. Agora, precisamos criar uma classe que será usada para obter os objetos declarados no arquivo mostrado:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> SpringBeanContext <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> SpringBeanContext instance<span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #009900;">&#123;</span>
        instance <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SpringBeanContext<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> ApplicationContext context<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> SpringBeanContext<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        context <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> ClassPathXmlApplicationContext<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;META-INF/spring/appcontext-*.xml&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Object</span> getBean<span style="color: #009900;">&#40;</span>Class<span style="color: #339933;">&lt;?&gt;</span> clazz<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        Map<span style="color: #339933;">&lt;?</span>,<span style="color: #339933;">?&gt;</span> beans <span style="color: #339933;">=</span> context.<span style="color: #006633;">getBeansOfType</span><span style="color: #009900;">&#40;</span>clazz<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>beans <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span> <span style="color: #339933;">&amp;&amp;</span> beans.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">return</span> beans.<span style="color: #006633;">values</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">iterator</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> NoSuchBeanDefinitionException<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;There's no bean of type &quot;</span> <span style="color: #339933;">+</span> clazz<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> SpringBeanContext getInstance<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> instance<span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// retorna o singleton</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Como apenas precisamos de um objeto da classe <code>SpringBeanContext</code>, esta foi programada como sendo um <a href="http://en.wikipedia.org/wiki/Singleton_pattern">Singleton</a>. Podemos ver que, quando o Singleton é instanciado, os arquivos de contexto &#8212; que seguem a convenção <code>appcontext-[modulo].xml</code> &#8212; são carregados pelo Spring. O método <code>getBean()</code> foi criado para que possamos obter objetos gerenciados pelo Spring.</p>
<h3>Definindo a anotação @InjectBean</h3>
<p>Agora, precisamos criar uma anotação que utilizaremos para indicar as dependências de nossos EJBs:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@Retention<span style="color: #009900;">&#40;</span>RetentionPolicy.<span style="color: #006633;">RUNTIME</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> @<span style="color: #000000; font-weight: bold;">interface</span> InjectBean <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span></pre></div></div>

<p>A anotação <code>@InjectBean</code>, que não possui parâmetros e é visível em <em>Runtime</em>, servirá para indicar os atributos que representam dependências. O <em>interceptor</em>, que definiremos a seguir, irá procurar por essa anotação nos EJBs interceptados. Então, para cada campo anotado com essa anotação, o <em>interceptor</em> irá obter o objeto correspondente do contexto do Spring e injetá-lo.</p>
<h3>O Interceptor</h3>
<p>Finalmente chegamos à classe que é responsável por fazer o trabalho pesado:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> SpringBeanInterceptor <span style="color: #009900;">&#123;</span>
&nbsp;
    @PostConstruct
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> injectSpringBean<span style="color: #009900;">&#40;</span>InvocationContext context<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003399;">Object</span> target <span style="color: #339933;">=</span> context.<span style="color: #006633;">getTarget</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Field</span> field <span style="color: #339933;">:</span> getAnnotatedFields<span style="color: #009900;">&#40;</span>target.<span style="color: #006633;">getClass</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            injectBean<span style="color: #009900;">&#40;</span>target, field<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        context.<span style="color: #006633;">proceed</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> List<span style="color: #339933;">&lt;</span>Field<span style="color: #339933;">&gt;</span> getAnnotatedFields<span style="color: #009900;">&#40;</span>Class<span style="color: #339933;">&lt;?&gt;</span> clazz<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        List<span style="color: #339933;">&lt;</span>Field<span style="color: #339933;">&gt;</span> fields <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> LinkedList<span style="color: #339933;">&lt;</span>Field<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Field</span> field<span style="color: #339933;">:</span> clazz.<span style="color: #006633;">getDeclaredFields</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>field.<span style="color: #006633;">getAnnotation</span><span style="color: #009900;">&#40;</span>InjectBean.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                fields.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>field<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">return</span> fields<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> injectBean<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> target, <span style="color: #003399;">Field</span> field<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003399;">Object</span> bean <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
        bean <span style="color: #339933;">=</span> SpringBeanContext.<span style="color: #006633;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getBean</span><span style="color: #009900;">&#40;</span>field.<span style="color: #006633;">getType</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>field.<span style="color: #006633;">isAccessible</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            field.<span style="color: #006633;">setAccessible</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        field.<span style="color: #006633;">set</span><span style="color: #009900;">&#40;</span>target, bean<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Nada de outro mundo, não? Perceba que usamos a anotação <code>@PostConstruct</code>, o que indica que o método anotado deve ser executado para um EJB após sua criação pelo <em>container</em>. Todo método interceptador deve retornar <code>void</code> e esperar um parâmetro do tipo <code>InvocationContext</code>. Neste método, utilizamos um pouco de <a href="http://en.wikipedia.org/wiki/Reflection_%28computer_science%29">Reflection</a> para injetar o objeto fornecido pelo Spring. Por fim, para que outros possíveis <em>interceptors</em> (e o próprio método sendo interceptado) possam ser invocados, chamamos <code>InvocationContext.proceed()</code>.</p>
<p>Para finalizar o exemplo, nos resta associar este <em>interceptor</em> com o EJB da aplicação. Uma forma simples de fazer isso seria através do uso da anotação <code>@Interceptors</code> nas classes e métodos desejados. Por exemplo:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@Stateless
@Interceptors<span style="color: #009900;">&#40;</span>SpringBeanInterceptor.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MultiplicationRulerBean <span style="color: #000000; font-weight: bold;">implements</span> MultiplicationRuler <span style="color: #009900;">&#123;</span>
&nbsp;
    @InjectBean
    <span style="color: #000000; font-weight: bold;">private</span> Calculator calculator<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Claro que, para este pequeno exemplo, esta abordagem poderia ser utilizada sem nenhum problema. Porém, definir o <em>interceptor</em> dessa forma é muito trabalhoso em situações onde temos muitos EJBs.</p>
<p>Para que possamos evitar o uso repetido da anotação <code>@Interceptors</code>, podemos fazer a configuração via <acronym title="eXtensible Markup Language">XML</acronym>, o que nos permite associar um <em>interceptor</em> a vários EJBs através do uso de curingas. Para isso, basta modificar o arquivo <code>ejb-jar.xml</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ejb-jar<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;interceptors<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;interceptor<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;description<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Spring-aware interceptor<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/description<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;interceptor-class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>com.destaquenet.tutorial.interceptor.SpringBeanInterceptor<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/interceptor-class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/interceptor<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/interceptors<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;assembly-descriptor<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;interceptor-binding<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ejb-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>*<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ejb-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;interceptor-class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>com.destaquenet.tutorial.interceptor.SpringBeanInterceptor<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/interceptor-class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/interceptor-binding<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/assembly-descriptor<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ejb-jar<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Neste caso, estamos associando o <em>interceptor</em> automaticamente a <strong>todos</strong> os EJBs, nos livrando de ter que configurar manualmente a associação do <em>interceptor</em> com possíveis novos EJBs que a aplicação venha a ter.</p>
<h3>Conclusão</h3>
<p>Venho observando que <em>frameworks</em> como o Spring e a especificação JavaEE estão trilhando caminhos diretamente opostos; enquando os primeiros estão crescendo descontroladamente e ficando cada vez mais complexos, o segundo está tirando a gordura e ficando mais simples de usar. Claro que cada desenvolvedor tem seus motivos para escolher um ou outro, mas eu particularmente já não vejo tanta vantagem em se adotar o Spring ao EJB. Por outro lado, penso ser mais interessante a <strong>junção</strong> dessas tecnologias de modo que cada uma contribua com o seu melhor.</p>
<p>Como vimos, a especificação JavaEE 5 &#8212; que foi projetada para ser estensível e fácil de usar &#8212; conta com componentes denominados <em>interceptors</em>, que nos fornecem um recurso <em>à la</em> <acronym title="Aspect Oriented Programming">AOP</acronym>, nos permitindo executar código em pontos bem definidos durante a execução da aplicação.</p>
<p>Eu nem preciso dizer que os <em>interceptors</em> podem ser usados para outras coisas além da mostrada aqui. Apenas para citar um exemplo, o <em>framework</em> <a href="http://www.jboss.com/products/seam">Seam</a> usa <em>interceptors</em> para implementar o que seus autores chamam de <a href="http://docs.jboss.com/seam/2.0.0.CR1/reference/en/html/concepts.html#d0e2958">Bijeção</a> &#8212; que permite que um componente qualquer possa receber/ejetar dependências de/para um contexto.</p>
<p>Os conceitos apresentados aqui podem ser adaptados para uso com outros <em>frameworks</em> de injeção de dependências, como <a href="http://code.google.com/p/google-guice/">Guice</a> e <a href="http://www.picocontainer.org/">PicoContainer</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2008/09/21/javaee-5-interceptors/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

