<?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>Fabrício Lemos &#187; Tratamento de Erros</title>
	<atom:link href="http://www.fabriciolemos.org/blog/tag/tratamento-de-erros/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.fabriciolemos.org/blog</link>
	<description>Blog sobre desenvolvimento de software</description>
	<lastBuildDate>Tue, 10 Nov 2009 18:54:00 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Template Method e Exceções</title>
		<link>http://www.fabriciolemos.org/blog/2008/template-method-e-excecoes/</link>
		<comments>http://www.fabriciolemos.org/blog/2008/template-method-e-excecoes/#comments</comments>
		<pubDate>Wed, 29 Oct 2008 21:13:32 +0000</pubDate>
		<dc:creator>Fabrício Lemos</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Padrões de Projeto]]></category>
		<category><![CDATA[Tratamento de Erros]]></category>

		<guid isPermaLink="false">http://www.fabriciolemos.org/blog/?p=65</guid>
		<description><![CDATA[Template Method sempre foi um dos meus padrões favoritos, porém quando aplicado de forma exagerada acho que ele trouxe mais prejuízos do que benefícios.]]></description>
			<content:encoded><![CDATA[<p class="western" style="margin-bottom: 0cm;"><a href="http://en.wikipedia.org/wiki/Template_method_pattern" target="_blank">Template Method</a> sempre foi um dos meus padrões favoritos, porém quando aplicado de forma exagerada acho que ele trouxe mais prejuízos do que benefícios.</p>
<p class="western" style="margin-bottom: 0cm;">A principal razão é que ele acaba dificultando o tratamento de erros da aplicação: ao padronizar o comportamento de alguma operação para uma hierarquia de classes, ele acaba também padronizando as exceções lançadas pelo método, e é aí que está o problema.</p>
<p class="western" style="margin-bottom: 0cm;">Um dos principais problemas que vejo em aplicações legadas é o tratamento de erros feito de forma inapropriada. Já vi algumas pessoas criticando, mas considero um excelente recurso da linguagem Java a existência de <a href="http://en.wikipedia.org/wiki/Exception_handling#Checked_exceptions" target="_blank">Checked Exceptions</a>, utilizadas para erros que podem precisar de um tratamento particular.</p>
<p class="western" style="margin-bottom: 0cm;">Na implementação de uma biblioteca ou de um framework, checked exceptions talvez não sejam tão interessantes. Mas, na implementação de aplicações, considero um recurso bem valioso principalmente para aquelas divididas em <a href="http://en.wikipedia.org/wiki/Layer_(object-oriented_design)" target="_blank">camadas</a>.</p>
<p class="western" style="margin-bottom: 0cm;">Template methods não casam bem com checked exceptions pelo seguinte motivo:</p>
<pre class="java">abstract protected void validar(Entidade entidade);

abstract protected void logarOperacao(Object algumaCoisa);

public void salvar (Entidade entidade) {
    this.validar(entidade);
    this.dao.persistir(entidade);
    this.logarOperacao(algumaCoisa);
}</pre>
<p class="western" style="margin-bottom: 0cm;">Um código como esse é comum em frameworks caseiros ou arquiteturas de referência. Geralmente fica em uma classe chamada MeuManagerGenerico, ou algo do tipo, e as diversas classes de negócio, específicas de cada entidade, devem implementar o método de validação e o método de log. O único problema com está abordagem é que você não está &#8220;amarrando&#8221; somente a assinatura e o algorítimo para salvar uma entidade, está também dizendo que nenhuma operação &#8220;salvar&#8221; do sistema lança uma checked exception.</p>
<p class="western" style="margin-bottom: 0cm;">A não ser que sua aplicação seja 100% <a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete" target="_blank">CRUD</a>, sem nenhuma restrição de unicidade em nenhum atributo, acho que essa é uma restrição muito forte e que não se aplica.</p>
<p class="western" style="margin-bottom: 0cm;">Dessa forma, se alguma regra de validação ou regra de negócio específica não for atendida, como você comunica para a camada superior (provavelmente a camada de visão) sobre o problema ocorrido? A única maneira é lançar unchecked exceptions.</p>
<p class="western" style="margin-bottom: 0cm;">Usando unchecked exception, como as camadas superiores saberão quais exceções lançadas pelas camadas inferiores? A única saída seria a camada inferior antecipar o tratamento dado ao erro, de maneira que a camada superior não precise trata-lo. Já vi muito essa abordagem com a exception tendo como atributo a chave da mensagem que será exibida ao usuário. Dessa forma a camada superior iria somente exibir a mensagem, não importando qual seja a exceção. Isso é um exemplo claro de quebra da divisão de responsabilidade entre as camadas. Se as camadas inferiores tem que antecipar de alguma forma a maneira como as camadas superiores fazem o tratamento de erro, porque você divide sua aplicação em camadas em primeiro lugar?</p>
<p class="western" style="margin-bottom: 0cm;">Esse um bom exemplo de que &#8220;amarração de código&#8221; e antecipação de necessidades podem trazer prejuízos não antecipados. Imagino que desenvolvedores que fazem template methods para operações com algoritmos simples como &#8220;salvar&#8221;, &#8220;atualizar&#8221;, &#8220;deletar&#8221;, etc só podem ter duas coisas em mente:</p>
<p class="western" style="margin-bottom: 0cm;"><strong>1. </strong> Economizar código.</p>
<p class="western" style="margin-bottom: 0cm;">Esse pensamento vem do falso sentimento de que uma aplicação enxuta é uma aplicação com pouco código. Temos que tomar cuidado pra não exagerar nas simplificações e não enxergar abstrações onde elas não existem ou são prejudiciais.</p>
<p class="western" style="margin-bottom: 0cm;"><strong>2.</strong> O desenvolvedor pode esquecer de fazer a validação ou gravar o log ou qualquer coisa do tipo, então &#8220;amarra-se&#8221; esse algoritmo em um template method.</p>
<p class="western" style="margin-bottom: 0cm;">Se seu desenvolvedor não sabe como fazer uma validação correta ou alguma dessas operações, ele não deveria colocar as mãos no código sem que estivesse fazendo <a href="http://www.improveit.com.br/xp/praticas/programacao_par" target="_blank">programação em par</a> com outro mais experiente.</p>
<p class="western" style="margin-bottom: 0cm;">Mesmo com essa armadilha, ainda acho válida a utilização do template method, mas somente nos raros casos onde se pode antecipar os erros de toda a hierarquia de classes e quando a complexidade do algoritmo justifique essa abordagem.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fabriciolemos.org/blog/2008/template-method-e-excecoes/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
