<?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>Mauricio Aniche &#187; ddd</title>
	<atom:link href="http://www.aniche.com.br/tag/ddd/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.aniche.com.br</link>
	<description>Clean code that works!</description>
	<lastBuildDate>Mon, 12 Jul 2010 15:03:58 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Como gerenciar a dependência entre entidades e repositórios?</title>
		<link>http://www.aniche.com.br/2009/09/como-gerenciar-a-dependencia-entre-entidades-e-repositorios/</link>
		<comments>http://www.aniche.com.br/2009/09/como-gerenciar-a-dependencia-entre-entidades-e-repositorios/#comments</comments>
		<pubDate>Sat, 26 Sep 2009 15:26:00 +0000</pubDate>
		<dc:creator>Mauricio Aniche</dc:creator>
				<category><![CDATA[oop]]></category>
		<category><![CDATA[teste de software]]></category>
		<category><![CDATA[ddd]]></category>

		<guid isPermaLink="false">/post/2009/09/26/Como-gerenciar-a-dependencia-entre-entidades-e-repositorios.aspx</guid>
		<description><![CDATA[Engraçado que esse é um assunto onde há sempre mais um &#8220;ponto&#8221; a acrescentar. Motivados pelo excelente post da Caelum e discussão do GUJ (onde ambos não são tão recentes assim), eu e o Eduardo Amuri discutimos mais alguns pontos&#8230; Alguns deles podem já ter sido abordados nos links anteriores, mas vale a revisão.
Eu ia [...]]]></description>
			<content:encoded><![CDATA[<p>Engraçado que esse é um assunto onde há sempre mais um &#8220;ponto&#8221; a acrescentar. Motivados pelo excelente <a id="xyw7" title="post da Caelum" href="http://blog.caelum.com.br/2007/06/09/repository-seu-modelo-mais-orientado-a-objeto/">post da Caelum</a> e <a id="wcnf" title="discussão do GUJ" href="http://www.guj.com.br/posts/list/60916.java">discussão do GUJ</a> (onde ambos não são tão recentes assim), eu e o <a id="lnsm" title="Eduardo Amuri" href="http://www.linkedin.com/pub/eduardo-amuri-antunes/12/8a6/828">Eduardo Amuri</a> discutimos mais alguns pontos&#8230; Alguns deles podem já ter sido abordados nos links anteriores, mas vale a revisão.</p>
<p>Eu ia pular a questão inicial, mas vou revisar para que facilite o entendimento do resto do post para quem não leu os links acima. <em>Uma entidade pode conhecer/utilizar um repositório? </em>Acho que a resposta é óbvia: Sim. Repositórios são conceitos de negócios, fazem parte do domínio, e por isso não há nada de errado em uma entidade conhecer um repositório. Não vou entrar no mérito de como o repositório deve ser implementado, não é o meu interesse no momento. Mas vamos lá&#8230; Ok, podemos ter entidades que <strong>dependem </strong>de um repositório, e o problema é: como gerenciar essa dependência?</p>
<p>A seguir, discutimos algumas abordagens para resolver esse problema e chegamos em algumas conclusões, das quais gostaria de compartilhar.</p>
<p><strong>Sugestão I: </strong><em>Receber o repositório pelo construtor</em><br />
A entidade deve possuir um construtor que receba a dependência.</p>
<p><strong>Vantagens:</strong></p>
<ul>
<li>A dependência fica explícita, ou seja, não há como criar uma entidade sem entregar a dependência já resolvida.</li>
</ul>
<p><strong>Problemas:</strong></p>
<ul>
<li>Torna o código menos legível, afinal sempre que for instanciar uma entidade, deve-se injetar seu repositório.<br />
Ex: <em>Pessoa mauricio = new Pessoa ( repositorioDePessoas );</em></li>
<li>Imagine uma entidade que depende de mais de um repositório (por quê não?). Imagine passar os diversos repositórios no construtor. Menos legível ainda&#8230;<br />
Ex: <em>Pessoa mauricio = new Pessoa ( repositorioDePessoas, repositorioDeXPTO, repositorioDeXYZ );</em></li>
<li>Isso fica pior ainda quando definimos um construtor que receba algum atributo, por exemplo.</li>
<li>Ex: <em>Pessoa mauricio = new Pessoa ( &#8220;mauricio&#8221;, &#8220;aniche&#8221;, repositorioDePessoas, repositorioDeXPTO );</em></li>
</ul>
<p><strong>Testabilidade:</strong></p>
<ul>
<li>É fácil injetar um mock no lugar da dependência, para facilitar o teste unitário da entidade.</li>
</ul>
<p><strong>Sugestão II:</strong> <em>Definir um setter para a dependência</em><br />
A entidade deve ter um método setDependencia() que receba a dependência.</p>
<p><strong>Vantagens:</strong></p>
<ul>
<li>Elimina o problema de resolver a dependência no momento da criação do objeto.</li>
</ul>
<p><strong>Problemas:</strong></p>
<ul>
<li>Você precisa setar a dependência sempre que for utilizar, e isso pode ser um problema. Você precisará fazer todo o tempo algum tipo de validação no código da entidade para saber se a dependência já foi injetada ou não.<br />
Ex: <em>public List&lt;XPTO&gt; pegaXpto(int abc) { if(repositorio!=null) repositorio.pegaX(abc); }</em></li>
</ul>
<p><strong>Testabilidade:</strong></p>
<ul>
<li>Também é fácil injetar um mock no lugar da dependência.</li>
</ul>
<p><strong>Sugestão III:</strong> <em>Utilizar o próprio repositório para injetar repositórios nas entidades<br />
</em>Conforme sugerido pelo Paulo Silveira e pelo Fabio Kung no post, sempre que um objeto for recuperado pelo seu repositório, o mesmo deve se &#8220;auto-injetar&#8221; antes de devolver o objeto.</p>
<p><strong>Vantagens:</strong></p>
<ul>
<li>A complexidade do gerenciamento desse dependência fica escondida no código do repositório.</li>
<li>O código a ser implementado, de maneira geral, é simples.</li>
</ul>
<p><strong>Problemas:<br />
</strong></p>
<ul>
<li>Apesar de ser simples, deve ser replicado em todos os métodos do repositório. Se o método do repositório retornar uma lista, por exemplo, deve-se repetir o processo em todos os elementos dessa lista.</li>
<li>Apenas as entidades que são recuperadas pelo repositório recebem a dependência. Entidades criadas em qualquer outro ponto do projeto não recebem essa dependência de forma automática. Isso pode causar o problema levantado na sugestão II.</li>
<li>Caso a entidade mude e venha a depender de um outro repositório, você terá muito código para alterar.</li>
</ul>
<p><strong>Testabilidade:</strong></p>
<ul>
<li>Da mesma maneira que o repositório injeta a dependência (através de um <em>setter</em>), pode-se injetar um mock.</li>
</ul>
<p><strong>Sugestão IV:</strong> <em>Injetar o repositório por AOP<br />
</em>Uma idéia bastante interessante seria injetar a dependência por AOP. Dessa maneira não importaria como o bean é instanciado, seja ele feito pelo JPA<em>, </em>Hibernate, etc, ou pelo programador. Essa foi uma sugestão levantada pelo Alessandro Lazarotti, <a id="rg1g" title="nesse post do GUJ" href="http://www.guj.com.br/posts/list/70275.java">nesse post do GUJ</a>.</p>
<p><strong>Vantagens:</strong></p>
<ul>
<li>O código fica bastante claro.</li>
</ul>
<p><strong>Problemas:</strong></p>
<ul>
<li>A implementação de um aspecto geralmente não é trivial.</li>
</ul>
<p><strong>Testabilidade:</strong></p>
<ul>
<li>Dependendo do modo que o aspecto for implementado, talvez não seja tão trivial injetar a dependência. Para facilitar, pode-se criar um <em>setter</em> exclusivamente para isso, mas não é muito elegante.</li>
</ul>
<p><strong>Sugestão V: </strong><em>Resolver a dependência dentro da própria entidade</em><br />
A idéia seria a própria entidade resolver a sua dependência. No caso, ela mesma invocaria o framework de DI, e recuperaria a instância da dependência. Pode-se até pensar em uma Factory para que a entidade não dependesse diretamente de uma implementação de framework de DI.</p>
<p><strong>Vantagens:</strong></p>
<ul>
<li>Solução bastante simples.</li>
<li>Acaba com o problema da necessidade da entidade validar se a dependência foi injetada ou não, já que ela mesma vai resolver.</li>
</ul>
<p><strong>Problemas:<br />
</strong></p>
<ul>
<li>Não é muito elegante fazer com que a própria classe resolva suas dependências.</li>
</ul>
<p><strong>Testabilidade:</strong></p>
<ul>
<li>Como é a própria classe que resolve a dependência, você precisará de um setter para conseguir injetar um mock. Como dito acima, não é muito legal.</li>
</ul>
<p>(*) Além do que foi citado acima, existe um outro problema, ortogonal ao das dependências, e diz respeito diretamente à implementação desse projeto em particular. Por estarmos discutindo uma aplicação web, o contexto do Spring está guardado dentro do contexto web. Para que um POJO qualquer recupere esse contexto, ele precisaria conhecer o <em>servletContext</em>. Ainda não encontrei uma maneira muito clara para resolver isso, mas minha sugestão é criar uma classe <em>singleton </em>que conteria um atributo com uma instância de contexto do Spring, e essa instância seria injetada por um <em>filter </em>ou um <em>listener</em> qualquer, que subiria logo após ao listener do Spring. A partir daí, todas as classes de domínio fariam acesso à esse <em>singleton</em> para capturar o contexto.</p>
<p>Portanto, é possível gerenciar essa dependência de diversas formas, todas elas com suas vantagens e desvantagens. E você, como faz?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aniche.com.br/2009/09/como-gerenciar-a-dependencia-entre-entidades-e-repositorios/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
