<?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>blog.caelum.com.br</title>
	<atom:link href="http://blog.caelum.com.br/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.caelum.com.br</link>
	<description>blog dos desenvolvedores da Caelum</description>
	<lastBuildDate>Thu, 02 Sep 2010 06:45:11 +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>Lançado Rails 3 &#8211; e apostila atualizada para download</title>
		<link>http://blog.caelum.com.br/2010/09/02/lancado-rails-3-e-apostila-atualizada-para-download/</link>
		<comments>http://blog.caelum.com.br/2010/09/02/lancado-rails-3-e-apostila-atualizada-para-download/#comments</comments>
		<pubDate>Thu, 02 Sep 2010 06:34:02 +0000</pubDate>
		<dc:creator>David Paniz</dc:creator>
				<category><![CDATA[apostila]]></category>
		<category><![CDATA[caelum]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rails 3]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=3068</guid>
		<description><![CDATA[Depois de dois anos de trabalho da junção do Merb com o Rails, saiu nesse fim de semana a versão final do Rails 3. E, para comemorar, a Caelum acaba de liberar a apostila atualizada do curso RR-71 Ruby On Rails 3 para download.

Entre as principais novidades, temos a nova API de query do ActiveRecord [...]]]></description>
			<content:encoded><![CDATA[<p>Depois de dois anos de trabalho da junção do Merb com o Rails, <a href="http://weblog.rubyonrails.org/2010/8/29/rails-3-0-it-s-done">saiu nesse fim de semana a versão final do Rails 3</a>. E, para comemorar, a Caelum acaba de liberar a apostila atualizada do <a href="http://www.caelum.com.br/curso/rr71">curso RR-71 Ruby On Rails 3</a> para download.</p>
<p><img src="http://blog.caelum.com.br/wp-content/uploads/2010/09/Schermata-2010-09-01-a-6.11.02-PM-300x164.png" alt="Rails 3" title="Rails 3" width="300" height="164" class="aligncenter size-medium wp-image-3089" /></p>
<p>Entre as principais novidades, temos a nova API de query do <code>ActiveRecord</code> (ARel), a nova sintaxe para definição de rotas, o unobstrusive JavaScript para desacoplamento do prototype como biblioteca padrão, além de melhorias no <code>ActionController</code> e <code>ActionMailer</code>. Mas a principal mudança nessa nova versão é seu <em>agnosticismo</em>, agora é possível substituir partes do Rails por outros frameworks de sua preferencia sem precisar sofrer como antigamente e quem escreve essas outras opções não precisa mais fazer hacks e código de difícil manutenção, tornando o Rails um verdadeiro ecossistema.</p>
<p>Por exemplo, o <b>ARel</b> nos provê uma nova maneira de montarmos as queries através de uma DSL mais elegante que os finders do Rails 2, e também possibilita adicionarmos filtros extras a uma query já existente como no exemplo abaixo:</p>
<pre class="brush: ruby;">
juridicas = Cliente.where(:tipo =&gt; &quot;PJ&quot;).order(&quot;nome&quot;)
inativos = juridicas.where(:ativo =&gt; false)
</pre>
<p>Para a nova definição de rotas, o Rails 3 traz diversas melhorias de sintaxe, entre elas, na declaração das rotas nomeadas:</p>
<pre class="brush: ruby;">
match 'cadastro', :controller =&gt; 'usuarios', :action =&gt; 'new'
# se acessar /cadastro vai para a action 'new' no usuarios_controller, mas não cria os helpers

match 'cadastro', :controller =&gt; 'usuarios', :action =&gt; 'new', :as =&gt; 'rota_cadastro'
# se acessar /cadastro vai para a action 'new' no usuarios_controller, mas agora ganhamos os
# helper_methods rota_cadastro_path e rota_cadastro_url
</pre>
<p>Se você ainda não conhece Rails, e quer começar já por essa nova versão, baixe agora a apostila do curso <a href="http://www.caelum.com.br/curso/rr71">RR-71 de Ruby on Rails</a>, que foi reformulada durante esses últimos meses acompanhando todas as mudanças no framework. Está liberada a versão da apostila beta. Envie seus comentários e sugestões!</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fblog.caelum.com.br%2F2010%2F09%2F02%2Flancado-rails-3-e-apostila-atualizada-para-download%2F&amp;linkname=Lan%C3%A7ado%20Rails%203%20%26%238211%3B%20e%20apostila%20atualizada%20para%20download"><img src="http://blog.caelum.com.br/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/2010/09/02/lancado-rails-3-e-apostila-atualizada-para-download/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Um produto para muitos clientes: implementando multitenancy</title>
		<link>http://blog.caelum.com.br/2010/08/23/um-produto-para-muitos-clientes-implementando-multitenancy/</link>
		<comments>http://blog.caelum.com.br/2010/08/23/um-produto-para-muitos-clientes-implementando-multitenancy/#comments</comments>
		<pubDate>Mon, 23 Aug 2010 22:19:52 +0000</pubDate>
		<dc:creator>Guilherme Silveira</dc:creator>
				<category><![CDATA[arquitetura]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[engenharia]]></category>
		<category><![CDATA[escalabilidade]]></category>
		<category><![CDATA[mercado]]></category>
		<category><![CDATA[chargeback]]></category>
		<category><![CDATA[clientes]]></category>
		<category><![CDATA[multitenant]]></category>
		<category><![CDATA[produto]]></category>
		<category><![CDATA[segurança]]></category>
		<category><![CDATA[simplicidade]]></category>
		<category><![CDATA[tradeoff]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=3010</guid>
		<description><![CDATA[São diversos as aplicações web disponíveis, como quadros eletrônicos, sistemas de tracking, email e aplicações para empresas, ou até mesmo controle de clientes e vendas. Eles até ganharam um pomposo nome dentro do cloud computing: Software as a Service (SAAS).
O que essas aplicações possuem em comum? Todas elas atendem diversos clientes sem que um tenha [...]]]></description>
			<content:encoded><![CDATA[<p>São diversos as aplicações web disponíveis, como <a href="http://pivotaltracker.com">quadros eletrônicos</a>, <a href="http://lighthouse.com">sistemas de tracking</a>, <a href="http://www.google.com/enterprise/">email e aplicações para empresas</a>, ou até mesmo <a href="http://salesforce.com">controle de clientes e vendas</a>. Eles até ganharam um pomposo nome dentro do cloud computing: Software as a Service (SAAS).</p>
<p>O que essas aplicações possuem em comum? Todas elas atendem diversos clientes sem que um tenha conhecimento da existência dos outros. </p>
<p>Em <a href="http://www.tectura.com.br/topics/abordagens_de_multitenant">um post recente no Tectura.com.br</a> foram discutidas vantagens e desvantagens de diversas abordagens para produtos com a necessidade de suportar mais de um tenant.</p>
<p>A <a href="http://msdn.microsoft.com/en-us/library/aa479086.aspx#mlttntda_topic2">Microsoft categoriza três tipos de abordagens</a> dependendo do nível de compartilhamento de recursos entre os clientes e apresente um relatório onde analisa os custos contra a segurança.</p>
<p>Em um extremo, nada é compartilhado entre cada cliente: para cada nova conta criada dentro de seu serviço, é criada uma nova máquina na cloud e uma instalação limpa é executada, com seu próprio banco.</p>
<p><center><div id="attachment_3057" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.caelum.com.br/wp-content/uploads/2010/08/dois-dois.png"><img src="http://blog.caelum.com.br/wp-content/uploads/2010/08/dois-dois-300x152.png" alt="Dois servidores, dois bancos" title="Dois servidores, dois bancos" width="300" height="152" class="size-medium wp-image-3057" /></a><p class="wp-caption-text">Nessa abordagem p processo de autorização é automático, um cliente é criado através da instalação automática de uma nova máquina virtual e os recursos são compartilhados se o ambiente for uma cloud.</p></div></center></p>
<p>Na outra ponta, tudo é compartilhado: novos clientes são inseridos no mesmo conjunto de máquinas e a instalação é feita através de um simples insert no banco, adicionando um novo cliente. Qual abordagem escolher?</p>
<p><center><div id="attachment_3060" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.caelum.com.br/wp-content/uploads/2010/08/um-um.png"><img src="http://blog.caelum.com.br/wp-content/uploads/2010/08/um-um-300x150.png" alt="Um servidor, um banco" title="Um servidor, um banco" width="300" height="150" class="size-medium wp-image-3060" /></a><p class="wp-caption-text">A autorização é feita programaticamente na aplicação, os recursos são compartilhados entre todas elas, escala-se tipicamente através do uso de load balancers e replicação master/slave e a cada novo cliente basta executar um insert no banco.</p></div></center></p>
<p>Em qualquer abordagem onde o banco seja compartilhado por diversas empresas, precisamos garantir a segurança dos dados de cada uma, para que nenhum acesso indevido ocorra, trazendo preocupações de autorização para dentro do código de nossa aplicação. Caso seja criado para cada cliente um banco em uma máquina no cloud, essa questão fica concentrada em um único ponto da arquitetura, a segurança está implícita.</p>
<p><center><div id="attachment_3058" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.caelum.com.br/wp-content/uploads/2010/08/dois-um.png"><img src="http://blog.caelum.com.br/wp-content/uploads/2010/08/dois-um-300x149.png" alt="Dois servidores, um banco" title="Dois servidores, um banco" width="300" height="149" class="size-medium wp-image-3058" /></a><p class="wp-caption-text">Diversos servidores e um banco implica em clientes não afetarem uns aos outros, um controle programático de autorização e novos clientes são criados a partir da instalação de um novo contexto web.</p></div></center></p>
<p>Ao mesmo tempo, o processo de customização de seu serviço por cliente também é afetada de acordo com o nível de compartilhamento de dados entre eles. Na abordagem onde os clientes compartilham o mesmo servidor web, a customização é uma preocupação de nossa aplicação, enquanto ao utilizarmos aplicações web distintas para cada cliente, podemos facilmente separar customizações por instância, por deploy efetuado.</p>
<p>A escalabilidade é afetada pois compartilhar recursos em memória na camada web, <a href="http://blog.caelum.com.br/2010/06/07/escalando-sistemas-com-solucoes-nosql/">entre eles dados cacheados do banco ou filas</a>, permitem diminuir o tempo de processamento ou de latência, aumentando o número de requisições suportados.</p>
<p>O processo de escalar também está diretamente ligado: quando uma máquina não aguentar mais as requisições, será levantada uma outra máquina que funcionará em cluster para um, n ou todos os clientes?</p>
<p>Outro fator importante é como limitar o uso do serviço de acordo com as regras contratadas pelo cliente e controlar o dano que um pode causar a outros. Em um pico de uso por parte dos usuários de um cliente, <a href="http://www.virtualizationconference.com/node/723565">ativamos o chargeback</a>, dependendo do tipo de serviço que é prestado. Implementações comuns de chargeback em cloud (<a href="http://www.vmware.com/virtualization/virtual-machine.html">baseados em virtualização</a>) permitem um pico de consumo temporário ou até mesmo mover a aplicação de uma máquina para outra sem que cliente algum perçeba o que está acontecendo.</p>
<p><center><div id="attachment_3058" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.caelum.com.br/wp-content/uploads/2010/08/dois-um.png"><img src="http://blog.caelum.com.br/wp-content/uploads/2010/08/dois-um-300x149.png" alt="Dois servidores, um banco" title="Dois servidores, um banco" width="300" height="149" class="size-medium wp-image-3058" /></a><p class="wp-caption-text">Diversos servidores e um banco implica em clientes não afetarem uns aos outros, um controle programático de autorização e novos clientes são criados a partir da instalação de um novo contexto web.</p></div></center></p>
<p>Ao invés daqueles usuários atrapalharem a performance de outros clientes, é alocado memória e processador distintos dos atuais para ele.</p>
<p>A simplicidade do código é um dos fatores mais afetados pela escolha feita: um código que sabe da existência de múltiplos clientes está diretamente ligado a uma chave que identifica o cliente atual. E essa ligação se reflete por todos os lados do código, uma vez que o comportamento da aplicação em geral depende dele: uma chave estrangeira, um relacionamento, que vai permear toda a aplicação.</p>
<p>Caso a aplicação implemente o suporte a multi tenant através de instalções web distintas, com configurações para cada cliente apontando para um bancos distintos, o código fica mais simples e fácil de manter, uma vez que não é necessário se preocupar com a existência de outros clientes.</p>
<p>Por fim, uma preocupação que surge para a empresa provedora dos serviços é de como agrupar os dados existentes em todos os clientes e gerar relatórios de administração e estatísticas que permitam a melhora do serviço prestado. Quando possuimos um único banco, escalado através de master slave ou múltiplos nós, basta executarmos queries longas (sql ou não), mas se o sistema estiver distribuido entre diversos bancos sem ligação entre si, <a href="http://cloudcomputing.sys-con.com/node/1086696">um processo de batch deve rodar para agrupar os dados e permitir o consumo posterior pelas ferramentas de BI</a>.</p>
<p><a href="http://blog.caelum.com.br/2010/07/21/entao-voce-quer-ser-um-arquiteto-java/">É importante analisar todos esses pontos antes de tomar a decisão</a> se o controle de espaço de aplicação por cliente será feito no nosso código, na camada web, no banco ou em algum outro ponto. Como discutimos bastante <a href="http://www.caelum.com.br/curso/fj-91-arquitetura-design-projetos-java/">no curso de arquitetura</a>, toda e qualquer decisão implica em um tradeoff: o importante é saber o que está sendo trocado e qual é o impacto disso.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fblog.caelum.com.br%2F2010%2F08%2F23%2Fum-produto-para-muitos-clientes-implementando-multitenancy%2F&amp;linkname=Um%20produto%20para%20muitos%20clientes%3A%20implementando%20multitenancy"><img src="http://blog.caelum.com.br/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/2010/08/23/um-produto-para-muitos-clientes-implementando-multitenancy/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>ConcurrentModificationException e os fail-fast iterators</title>
		<link>http://blog.caelum.com.br/2010/08/18/concurrentmodificationexception-e-os-fail-fast-iterators/</link>
		<comments>http://blog.caelum.com.br/2010/08/18/concurrentmodificationexception-e-os-fail-fast-iterators/#comments</comments>
		<pubDate>Wed, 18 Aug 2010 15:58:38 +0000</pubDate>
		<dc:creator>Paulo Silveira</dc:creator>
				<category><![CDATA[collections]]></category>
		<category><![CDATA[concorrência]]></category>
		<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[oo]]></category>
		<category><![CDATA[ArrayList]]></category>
		<category><![CDATA[Collections.synchronizedList]]></category>
		<category><![CDATA[concurrent]]></category>
		<category><![CDATA[ConcurrentModificationException]]></category>
		<category><![CDATA[iterator]]></category>
		<category><![CDATA[java.util]]></category>
		<category><![CDATA[programação concorrente]]></category>
		<category><![CDATA[Queue]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=2973</guid>
		<description><![CDATA[A java.util.ConcurrentModificationException costuma surpreender a muitos: como uma exception com esse nome pode aparecer mesmo em uma aplicação single threaded, que não envolve concorrência alguma no acesso dessa coleção?
Para entender melhor, vale relembrar que as coleções muito antigas, como Vector e Hashtable, são thread safe, implementado através do uso do synchronized em seus métodos e [...]]]></description>
			<content:encoded><![CDATA[<p>A <code>java.util.ConcurrentModificationException</code> costuma surpreender a muitos: como uma exception com esse nome pode aparecer mesmo em uma aplicação single threaded, que não envolve concorrência alguma no acesso dessa coleção?</p>
<p>Para entender melhor, vale relembrar que as coleções muito antigas, como <code>Vector</code> e <code>Hashtable</code>, são <em>thread safe</em>, implementado através do uso do <code>synchronized</code> em seus métodos e iteradores (<code>Enumeration</code> na época). No Java 1.2, com a entrada das interfaces <code>Collection</code>, <code>List</code>, <code>Set</code> e <code>Iterator</code>, as novas implementações optaram por não ser thread safe, dado o custo de performance que o <code>synchronized</code> apresentava (hoje em dia é muito, muito menor), e de que a grande maioria dos casos de uso dessas estruturas não necessitavam de <em>thread safety</em>.</p>
<p>Essa novidade, das novas coleções não serem preparadas para o uso em um ambiente multi thread, poderia causar surpresas para quem não a estivesse esperando. Em vez de deixar alguém percorrer uma coleção através de um <code>Iterator</code> enquanto ela é modificada concorrentemente (acarretando em dados incorretos, <code>null</code>s, etc)  optou-se por evitar esses casos. Para isso tenta-se &#8220;adivinhar&#8221; quando houver mais de uma thread trabalhando com a mesma coleção concorrentemente (uma modificando a coleção, e outra iterando-a).</p>
<p>Como fizeram isso sem usar mecanismos de lock? Usando um contador!</p>
<p>Imagine que a cada modificação na estrutura de uma <code>ArrayList</code>, nós incrementamos um <code>contador</code> (<code>modCount</code>). Quando um <code>Iterator</code> é requisitado pelo método <code>iterator()</code>, esse contador é guardado como atributo (<code>expectedModCount</code>). Cada vez que você invocar os métodos <code>next()</code> e <code>remove()</code> (lembrando que temos apenas 3 métodos na interface <a href="http://download.oracle.com/javase/6/docs/api/java/util/Iterator.html"><code>Iterator</code></a>), esse iterador vai checar se o contador da <code>ArrayList</code> é exatamente igual ao número que era esperado, isso é, tem o mesmo valor desde quando começamos a percorrer seus elementos. Caso os valores sejam diferentes, a <code>java.util.ConcurrentModificationException</code> é lançada, pois foi detectada uma modificação concorrente (<em>comodification</em>).</p>
<p>Mas como essa exceção pode ocorrer mesmo quando não temos outras threads acessando a mesma coleção? O problema é exatamente essa tentativa de detectar um acesso concorrente:</p>
<pre class="brush: java;">
List&lt;String&gt; nomesDosAlunos = new ArrayList&lt;String&gt;();
// ...  popula lista com strings
for (String nome : nomesDosAlunos) {
	if (nome.equals(&quot;nome procurado&quot;)) {
		nomesDosAlunos.remove(nome);
	}
}
</pre>
<p>Esse código vai lançar <code>ConcurrentModificationException</code> caso encontre a <code>String</code> procurada: </p>
<pre class="brush: plain;">
Exception in thread &quot;main&quot; java.util.ConcurrentModificationException
	at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
	at java.util.AbstractList$Itr.next(AbstractList.java:343)
	...
</pre>
<p>Isso ocorre pois o <code>Iterator</code> utilizado internamente nesse laço vai detectar, na próxima chamada ao seu método <code>next()</code>, que o número de modificações desta <code>ArrayList</code> é diferente de quando ele foi instanciado. Essa stacktrace pode confundir um pouco, já que o uso do <em>enhanced for</em> esconde a utilização do <code>iterator</code>, e não conseguimos ver explicitamente a invocação do método <code>next</code> na linha do <code>for</code>.</p>
<p>Repare que a detecção nesse caso single threaded é arbitrária para evitar casos estranhos (se removessemos o objeto da lista, o <code>iterator</code> deveria ainda percorre-lo?), e coleções sem <em>fail fast iterators</em> vão possibilitar esse tipo de remoção e outras modificações sem lançar excessões. Como então evitar essa exception nas coleções com <em>fail fast iterators</em>? Utilizando o <code>iterator.remove()</code> em vez do <em>enhanced for</em>:</p>
<pre class="brush: java;">
List&lt;String&gt; nomesDosAlunos = new ArrayList&lt;String&gt;();
// ...  popula lista com strings
for (Iterator&lt;String&gt; i = nomesDosAlunos.iterator(); i.hasNext();) {
	String nome = i.next();
	if (nome.equals(&quot;nome procurado&quot;)) {
		i.remove();
	}
}
</pre>
<p>Esses iteradores são chamados de <strong><em>fail-fast</em></strong> por possuirem essa característica de falhar quando uma modificação concorrente é detectada. Essa é apenas uma <strong>tentativa</strong> do <code>Iterator</code> em encontrar possíveis bugs, e existem casos e combinações em que a modificação concorrente pode passar desapercebida por esse mecanismo, e você não deve se basear nessa exception para garantir que sua aplicação é <em>thread safe</em>.</p>
<p>E se precisarmos usar uma lista em ambiente multi thread e percorrer seu iterator enquanto a modificamos? Podemos usar a <code><a href="http://download.oracle.com/javase/6/docs/api/java/util/concurrent/CopyOnWriteArrayList.html">CopyOnWriteArrayList</a></code> (nos casos de muita leitura e pouca escrita) ou ainda, se não for precisar de acesso aleatório aos elementos, utilizar uma <code>Queue</code> como a <code><a href="http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html">ConcurrentLinkedQueue</a></code>. Utilizar o antigo <code>Vector</code> ou a própria <code>ArrayList</code> em conjunto com <code><a href="http://download.oracle.com/javase/6/docs/api/java/util/Collections.html#synchronizedList(java.util.List)">Collections.synchronizedList</a></code> é thread safe e não vai lançar <code>ConcurrentModificationException</code> desde que você sincronize o uso de seus iterators:</p>
<pre class="brush: java;">
synchronized(nomesDosAlunos) {
	for (String nome : nomesDosAlunos)
		System.out.println(nome);
}
</pre>
<p>A performance dessas diferentes escolhas pode mudar drasticamente dependendo do contexto de sua aplicação. Pode também não ser necessário utilizar uma coleção que se preocupa com <em>thread safety</em>: algumas vezes basta diminuir o escopo da coleção (pode não ser necessário deixá-la na session, por exemplo) ou ainda trabalhar com cópias defensivas.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fblog.caelum.com.br%2F2010%2F08%2F18%2Fconcurrentmodificationexception-e-os-fail-fast-iterators%2F&amp;linkname=ConcurrentModificationException%20e%20os%20fail-fast%20iterators"><img src="http://blog.caelum.com.br/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/2010/08/18/concurrentmodificationexception-e-os-fail-fast-iterators/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>As 7 práticas para um site otimizado</title>
		<link>http://blog.caelum.com.br/2010/07/29/top-7-praticas-para-um-site-otimizado/</link>
		<comments>http://blog.caelum.com.br/2010/07/29/top-7-praticas-para-um-site-otimizado/#comments</comments>
		<pubDate>Thu, 29 Jul 2010 17:28:07 +0000</pubDate>
		<dc:creator>Sérgio Lopes</dc:creator>
				<category><![CDATA[css]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[otimização]]></category>
		<category><![CDATA[user experiencie]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[cdn]]></category>
		<category><![CDATA[expires]]></category>
		<category><![CDATA[gzip]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[jpeg]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[redimensionamento]]></category>
		<category><![CDATA[yslow]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=2987</guid>
		<description><![CDATA[Todo mundo gosta de sites rápidos. Seus primos não sabem dizer se você tem um arquitetura escalável, se seu banco NoSQL é mais robusto ou se é melhor usar Web Services SOAP ou REST. Mas eles sabem dizer duas informações com precisão: se seu site é bonito e se ele é rápido. Performance,  medida [...]]]></description>
			<content:encoded><![CDATA[<p>Todo mundo gosta de sites rápidos. Seus primos não sabem dizer se você tem um arquitetura escalável, se seu banco NoSQL é mais robusto ou se é melhor usar Web Services SOAP ou REST. Mas eles sabem dizer duas informações com precisão: se seu site é bonito e se ele é rápido. <strong>Performance</strong>,  medida pelo usuário, é o que te diz se a velocidade de resposta da sua aplicação é aceitável. E, assim como usuários não se cansam de bordas redondas e sombrinhas bonitas, sempre haverá otimizações possíveis para tornar seu site mais rápido.</p>
<p>Inspirado pela recente edição 2010 da <a href="http://en.oreilly.com/velocity2010">Velocity Conference</a> organizada pela O&#8217;Reilly e por uma <a href="http://blog.caelum.com.br/2010/05/27/ultimos-aprendizados-e-inovacoes-na-caelum/">palestra recente que dei com o Alberto Souza aqui na Caelum</a>, além de discussões que aparecem no <a href="http://www.caelum.com.br/curso/wd-43-desenvolvimento-web-html-css-javascript/">nosso curso que trata de HTML, CSS e Javascript</a>, selecionei um punhado de dicas para deixar qualquer site ou aplicação Web mais rápido em instantes. Meu TOP 7 não pretende ser uma lista completa e nem detalhada de boas práticas. É mais um guia rápido sobre tudo o que você deveria fazer em qualquer site antes de perguntar a opinião dos seus primos &#8211; ou do seu chefe, ou de qualquer usuário. Eis então:</p>
<p><img src="http://blog.caelum.com.br/wp-content/uploads/2010/07/Train+series+-+Motion+blur+of+a+fast+moving+train.-e1280395129893.jpeg"  width="480" height="166" class="aligncenter size-full wp-image-2997" /></p>
<h3><u>TOP 7 das Otimizações na Web:</u></h3>
<p></p>
<p><strong>0. <a href="http://brunopereira.org/2010/06/20/acelerando-seu-site-parte-1-habilitando-compressao/">Habilite GZIP</a> em todas as suas páginas</strong>. Se você ainda não fez isso, pare imediatamente de ler esse post e faça. É o passo zero, nem vou contá-lo. Dicas de como fazer no <a href="http://tomcat.apache.org/tomcat-7.0-doc/config/http.html#Standard_Implementation">Tomcat</a>, <a href="http://blog.max.berger.name/2010/01/jetty-7-gzip-filter.html">Jetty</a>, <a href="http://httpd.apache.org/docs/2.0/mod/mod_deflate.html">Apache</a>, <a href="http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/25d2170b-09c0-45fd-8da4-898cf9a7d568.mspx?mfr=true">IIS</a>.</p>
<p><strong>1. Agrupe arquivos JavaScript/CSS</strong>. 90% do trabalho de otimização consiste em diminuir o número de requests feito na página e o peso de cada um deles. Você usa JQuery (ou qualquer outro framework) com JQuery UI e mais meia dúzia de plugins, sem contar o código JS da sua aplicação? Junte tudo no menor número de arquivos possíveis para evitar muitos requests. Mesma coisa com CSS, um arquivo com tudo basta. Mas gosta de manter as coisas organizadas ao invés de escrever um arquivo com milhares de linhas? Então junte essas coisas dinamicamente como faz <a href="http://cotnet.diggstatic.com/js/loader/464/JS_Libraries,jquery%7CClass%7Canalytics%7Clightbox%7Clabel%7Cjquery-dom%7Cjquery-cookie">o pessoal do Digg</a> ou faça o serviço no build da aplicação como preferimos <a href="http://www.caelum.com.br/css/caelum.package.css">aqui na Caelum</a>.</p>
<p><strong>2. Comprima o JavaScript/CSS</strong>. Você escreve JS/CSS elegante, bem documentado, com código organizado e variáveis de nomes legíveis. Mas seus primos não se importa com isso, eles querem um site rápido e isso significa não trafegar no request bytes e mais bytes de documentação ou de código legível. Comprima todo o seu código JavaScript e CSS usando o <a href="http://developer.yahoo.com/yui/compressor/">YUI Compressor</a> ou o <a href="http://code.google.com/closure/compiler/">Google Closure Compiler</a>. Faça isso em build time ou dinamicamente.</p>
<p><strong>3. Otimize suas imagens com Smush-it</strong>. Nem todos os KB de suas imagens são necessários para o cliente. Arquivos JPEG possuem uma série de metadados e PNGs possuem palhetas de cores. Remova vários KBs desnecessários de suas imagens usando o <a href="http://www.smushit.com/ysmush.it/">Yahoo Smush-it</a> em todas elas.</p>
<p><strong>4. Coloque CSS no topo e JavaScript embaixo</strong>. Simples assim. Referencie os seus CSS no &lt;head&gt; com &lt;link&gt; para evitar o <a href="http://en.wikipedia.org/wiki/Flash_of_unstyled_content">flash effect</a>, e coloque seus scripts logo antes do fechamento do &lt;body&gt; para não atrasar a renderização da tela.</p>
<p><strong>5. Não redimensione imagens no HTML</strong>. Não use os atributos <em>width</em> e <em>height</em> das imagens para redimensionar seu tamanho. Sirva as imagens já com tamanho certo e otimizadas. Mas coloque sempre o <em>width</em> e <em>height</em> de todas as imagens para ajudar o browser nos cálculos da renderização da página.</p>
<p><strong>6. Configure o Expires corretamente</strong>. Use o cache do navegador para prover uma melhor experiência ao usuário no segundo request &#8211; seja no retorno ao site ou navegando para a próxima página. Permita também que Proxies entre seu servidor e o cliente cacheiem elementos do seu site para evitar um download demorado. Configure o <a href="http://developer.yahoo.com/performance/rules.html#expires">header de Expires</a> de todo seu conteúdo estático (JS, CSS, imagens) com alguns dias de duração.</p>
<p><strong>7. Use YSlow e PageSpeed</strong>. Depois que você fez todas as otimizações anteriores, instale o <a href="http://developer.yahoo.com/yslow/">YSlow</a> e o <a href="http://code.google.com/speed/page-speed/">PageSpeed</a> para um diagnóstico detalhado de seu site. Monitore sua performance constantemente e vá implementando sempre novas otimizações. Seus usuários agradecem.</p>
<p></p>
<p>Esse <strong>TOP 7</strong> são todas as otimizações que você deveria ter feito <em>ontem</em> em qualquer site seu antes de começar a falar em performance. Há muitas outras práticas, algumas mais complicadas, como <a href="http://spriteme.org/">CSS Sprites</a>, <a href="http://developer.yahoo.com/performance/rules.html#cdn">usar CDNs</a>, <a href="http://code.google.com/speed/page-speed/docs/request.html#MinimizeRequestSize">otimizar seus cookies</a>, fazer <a href="http://developer.yahoo.com/performance/rules.html#preload">preload</a> e <a href="http://developer.yahoo.com/yui/imageloader/">postload</a> de conteúdo, ou <a href="http://code.google.com/p/htmlcompressor/">comprimir seu HTML</a>. Dependendo da tecnologia que você usa no seu sistema, você terá maior ou menor facilidade de aplicar todas essas práticas: no JSF e ASP.NET você terá benefícios para desenhar sua interface, mas muito mais trabalho de fazer esse ajuste fino; com Struts, Rails, ASP.NET MVC, VRaptor e frameworks action based, será o contrário.</p>
<p><strong><u>Bônus: Onde ir depois?</u></strong></p>
<ul>
<li><a href="http://developer.yahoo.com/performance/rules.html">Práticas de performance do pessoal do Yahoo YSlow</a></li>
<li><a href="http://code.google.com/speed/page-speed/docs/rules_intro.html">Boas práticas do pessoal do Google PageSpeed</a></li>
<li><a href="http://en.oreilly.com/velocity2010">Slides e vídeos das palestras do Velocity 2010 com o que há de mais novo em discussão</a></li>
</ul>
<p>E você, que outras práticas aplica no seu website?</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fblog.caelum.com.br%2F2010%2F07%2F29%2Ftop-7-praticas-para-um-site-otimizado%2F&amp;linkname=As%207%20pr%C3%A1ticas%20para%20um%20site%20otimizado"><img src="http://blog.caelum.com.br/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/2010/07/29/top-7-praticas-para-um-site-otimizado/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
		</item>
		<item>
		<title>Possibilidades de design no uso do seu Generic DAO</title>
		<link>http://blog.caelum.com.br/2010/07/26/possibilidades-de-design-no-uso-do-seu-generic-dao/</link>
		<comments>http://blog.caelum.com.br/2010/07/26/possibilidades-de-design-no-uso-do-seu-generic-dao/#comments</comments>
		<pubDate>Tue, 27 Jul 2010 02:57:38 +0000</pubDate>
		<dc:creator>Lucas Cavalcanti</dc:creator>
				<category><![CDATA[arquitetura]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[oo]]></category>
		<category><![CDATA[práticas]]></category>
		<category><![CDATA[dao]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[di]]></category>
		<category><![CDATA[generic dao]]></category>
		<category><![CDATA[herança]]></category>
		<category><![CDATA[repository]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=2948</guid>
		<description><![CDATA[Muitas vezes, quando estamos criando nosso sistema temos a tentação de criar o GenericDAO para não ter que ficar repetindo as operações CRUD e listagens.
O maior problema com o GenericDAO é que não necessariamente todas as operações fazem sentido para uma determinada classe. Daí o que fazer se, por exemplo, não faz sentido excluir um [...]]]></description>
			<content:encoded><![CDATA[<p>Muitas vezes, quando estamos criando nosso sistema temos a tentação de criar o <a href="http://blog.caelum.com.br/2006/10/29/brincando-com-generics-o-bizarregenericdao/">GenericDAO</a> para não ter que ficar repetindo as operações <em>CRUD</em> e listagens.</p>
<p>O maior problema com o <code>GenericDAO</code> é que não necessariamente todas as operações fazem sentido para uma determinada classe. Daí o que fazer se, por exemplo, não faz sentido excluir um pagamento?</p>
<pre class="brush: java;">
public class PagamentoDAO
          extends GenericDAO&lt;Pagamento&gt; {

     @Override
     public void excluir(Pagamento pagamento) {
         throw new UnsupportedOperationException();
     }
}
</pre>
<p>Não parece uma solução muito elegante, mas é um dos únicos jeitos de proibir uma operação declarada na classe mãe, e ainda assim, só funciona em tempo de execução. Esse é um dos principais motivos para muitos não gostarem de usar o <code>GenericDAO</code> e <a href="http://blog.caelum.com.br/2006/10/14/como-nao-aprender-orientacao-a-objetos-heranca/">preferirem usar composição ao invés de herança</a>. Mas como fazer para não repetir o código <b>trivial</b> das operações do <em>CRUD</em>?</p>
<p>Um dos jeitos é usar uma outra abstração de persistência de objetos: o <a href="http://martinfowler.com/eaaCatalog/repository.html">Repository</a>. Com o <em>Repository</em>, temos um lugar onde podemos guardar e buscar por objetos, não importando como fazemos isso. O <em>DAO</em> já está muito ligado com armazenamento em banco de dados, e foi criado quando as operações do BD eram muito trabalhosas (em especial no <em>JDBC</em>).</p>
<p>E como juntar o <em>Repository</em> com o <code>GenericDAO</code>? O <em>Repository</em> pode ser definido, por exemplo, como uma interface, e aí podemos fazer o seguinte: se, para um pagamento, faz sentido apenas salvar e listar, mas não excluir, então criamos a interface:</p>
<pre class="brush: java;">
public interface PagamentoRepository {
    void salva(Pagamento pagamento);
    Pagamento busca(Long id);
    List&lt;Pagamento&gt; lista();
}
</pre>
<p>E usamos o <code>GenericDAO</code> como <b>implementação</b> dessa interface:</p>
<pre class="brush: java;">
class PagamentoDAO
          extends GenericDAO&lt;Pagamento&gt;
          implements PagamentoRepository {
   // implementacao extra
}
</pre>
<p>E no nosso código de domínio &#8220;<strong>nunca</strong>&#8221; referenciaremos o <code>PagamentoDAO</code>, apenas o <code>PagamentoRepository</code>, assim mesmo que a <a href="http://www.arquiteturajava.com.br/livro/programe-voltado-a-interface-nao-a-implementacao.pdf">implementação saiba fazer mais coisas</a>, a interface só expõe as operações suportadas.</p>
<p>Se você usa <a href="http://www.arquiteturajava.com.br/livro/inversao-de-controle-cade-minha-chave-de-fenda.pdf">Injeção de Dependências</a> e algum framework que a suporta (como o <a href="http://vraptor.caelum.com.br">VRaptor</a>, Spring ou Java EE6), você pode deixar os <em>DAO</em>s apenas como infraestrutura, e usar os <em>Repositories</em> como interfaces públicas da sua aplicação:</p>
<pre class="brush: java;">
public class PagamentoController {
    public PagamentoController(PagamentoRepository repository) {
         this.repository = repository;
    }

    public void salva(Pagamento pagamento) {
         // validações e outras regras
         repository.salva(pagamento);
    }
}
</pre>
<p>Ainda poderíamos melhorar o nome do nosso repositório para <code>BaseDePagamentos</code>, <code>ContasAPagar</code> ou ainda <code>Pagamentos</code>, evitando usar sufixos nas classes. Usando abstrações e padrões simples conseguimos evitar repetição de código sem perder a semântica e restrições das nossas classes de modelo, além de esconder detalhes de implementação.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fblog.caelum.com.br%2F2010%2F07%2F26%2Fpossibilidades-de-design-no-uso-do-seu-generic-dao%2F&amp;linkname=Possibilidades%20de%20design%20no%20uso%20do%20seu%20Generic%20DAO"><img src="http://blog.caelum.com.br/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/2010/07/26/possibilidades-de-design-no-uso-do-seu-generic-dao/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Então você quer ser um arquiteto Java?</title>
		<link>http://blog.caelum.com.br/2010/07/21/entao-voce-quer-ser-um-arquiteto-java/</link>
		<comments>http://blog.caelum.com.br/2010/07/21/entao-voce-quer-ser-um-arquiteto-java/#comments</comments>
		<pubDate>Wed, 21 Jul 2010 23:40:32 +0000</pubDate>
		<dc:creator>Paulo Silveira</dc:creator>
				<category><![CDATA[arquitetura]]></category>
		<category><![CDATA[caelum]]></category>
		<category><![CDATA[integração]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[fowler]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=2808</guid>
		<description><![CDATA[Durante o atual processo de revisão do livro de Arquitetura e Design de Software, discussões apareceram sobre o termo arquiteto. Antes de definir o que faz um arquiteto, há o termo arquitetura. 
O que é a arquitetura de uma aplicação?
Uma pergunta difícil de responder. Entre as definições mais antigas, Roy Fielding possui um bom texto [...]]]></description>
			<content:encoded><![CDATA[<p>Durante o atual processo de revisão do livro de <a href="http://www.arquiteturajava.com.br">Arquitetura e Design de Software</a>, discussões apareceram sobre <a href="http://martinfowler.com/ieeeSoftware/whoNeedsArchitect.pdf">o termo <strong>arquiteto</strong></a>. Antes de definir o que faz um arquiteto, há o termo <strong>arquitetura</strong>. </p>
<div id="attachment_2942" class="wp-caption aligncenter" style="width: 511px"><a href="http://blog.caelum.com.br/wp-content/uploads/2010/07/neo-architect.jpg"><img src="http://blog.caelum.com.br/wp-content/uploads/2010/07/neo-architect.jpg" alt="" title="neo-architect" width="501" height="216" class="size-full wp-image-2942" /></a><p class="wp-caption-text">Quem é o arquiteto? Aquele que senta sozinho e toma todas as grandes decisões?</p></div>
<p><strong>O que é a arquitetura de uma aplicação?</strong><br />
Uma pergunta difícil de responder. Entre as definições mais antigas, Roy Fielding possui um bom texto no primeiro capítulo de sua <a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/software_arch.htm">dissertação de doutorado</a>. O Instituto de Engenharia de Software da Universidade de Carnegie Mellon <a href="http://www.sei.cmu.edu/architecture/start/definitions.cfm">apresenta diferentes definições</a>, <a href="http://www.sei.cmu.edu/architecture/start/bibliographicdefs.cfm">algumas clássicas</a> e bastante conhecidas, como &#8220;<em>arquitetura é a estrutura do sistema, composta de componentes, as propriedades que são visíveis externamente desses componentes e o relacionamento entre eles</em>&#8220;. </p>
<p><a href="http://martinfowler.com/articles/designDead.html#id21865">Nas palavras de Martin Fowler</a>, &#8220;<em>o termo arquitetura envolve a noção dos principais elementos do sistema, <strong>as peças que são difíceis de mudar</strong>. Uma fundação na qual o resto precisa ser construído</em>&#8220;. Fowler <a href="http://martinfowler.com/ieeeSoftware/whoNeedsArchitect.pdf">reformula sua definição de arquitetura</a> e a define como &#8220;<em>as peças que as pessoas acham que é difícil de mudar</em>&#8220;.  No mesmo artigo Ralph Johnson, do GoF, diz que arquitetura &#8220;<em>é o conjunto de decisões de design que gostaríamos de ter feito no começo do projeto</em>&#8221; e termina com uma definição mais abrangente: &#8220;<em>arquitetura é tudo aquilo que importa</em>&#8220;. Com tantas definições, talvez seja mais fácil diferenciarmos design de arquitetura.</p>
<p><strong>Qual é a diferença de design e arquitetura de software?</strong><br />
Aqui também temos uma resposta clássica na literatura: a arquitetura é responsável pelos requisitos não-funcionais, e o design pelos funcionais. Mas parece que essa distinção não é tão clara assim para muitos outros autores.</p>
<p><a href="http://www.ibm.com/developerworks/java/library/j-eaed10/index.html#distinguishing">Neal Ford apresenta uma distinção</a> simples, realçando que o design é feito em cima do que foi decidido pela arquitetura, e por isso o que faz parte da arquitetura é mais difícil de mudar. Devemos minimizar as peças que dificultam mudanças do nosso design, mas é impossível eliminar todas, além de que flexibilidade sempre vem a um custo de complexidade.</p>
<p><center><a href="http://blog.caelum.com.br/wp-content/uploads/2010/07/design.jpg"><img src="http://blog.caelum.com.br/wp-content/uploads/2010/07/design-150x150.jpg" alt="" title="design" width="150" height="150" class="aligncenter size-thumbnail wp-image-2966" /></a></center></p>
<p>É difícil criar um distinção maior entre os dois. No livro Patterns of Enterprise Application Architecture, Fowler diz que &#8220;<em>alguns dos padrões nesse livro  podem ser chamados arquiteturais, já que representam decisões importantes sobre essas partes; outros são mais sobre design e te ajudam a implementar essa arquitetura. Eu não faço nenhuma tentativa forte de separar esses dois, já que é <strong>o que é arquitetural ou não é subjetivo</strong></em>&#8220;.</p>
<p><strong>O arquiteto deve saber programar na plataforma em questão?</strong><br />
Sem dúvida. Cada vez mais vemos que o <a href="http://www.slideshare.net/pcalcado/expressive-design-in-20-minutes">design e a implementação devem ser trabalhados juntos</a>. A imagem de um <a href="http://www.infoq.com/presentations/agilists-and-architects">arquiteto distante sem profundo conhecimento técnico que apenas toma as grandes decisões</a> ficou pra trás: conhecimento técnico e a capacidade de liderança são as características fundamentais. </p>
<p>Mais do que querer ser o poderoso arquiteto que apenas despacha ordens e toma todas as grandes decisões, cada vez mais enxergamos que o caminho é ser o líder que incentiva essa tomada de decisão, além de ser um exímio  programador. Parafraseando mais uma vez Martin Fowler, &#8220;<em>&#8230;o arquiteto deve ser como um guia&#8230; que é um experiente e capacitado membro da equipe que ensina aos outros a melhor se virarem, ainda assim ele está sempre lá para as partes mais complicadas</em>&#8220;. </p>
<p>Vale lembrar que <a href="http://norvig.com/21-days.html">precisamos de mais de 10 mil horas, ou 10 anos, para dominar uma linguagem</a>.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fblog.caelum.com.br%2F2010%2F07%2F21%2Fentao-voce-quer-ser-um-arquiteto-java%2F&amp;linkname=Ent%C3%A3o%20voc%C3%AA%20quer%20ser%20um%20arquiteto%20Java%3F"><img src="http://blog.caelum.com.br/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/2010/07/21/entao-voce-quer-ser-um-arquiteto-java/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>Arredondamento no Java: do double ao BigDecimal</title>
		<link>http://blog.caelum.com.br/2010/07/15/arredondamento-no-java-do-double-ao-bigdecimal/</link>
		<comments>http://blog.caelum.com.br/2010/07/15/arredondamento-no-java-do-double-ao-bigdecimal/#comments</comments>
		<pubDate>Thu, 15 Jul 2010 20:56:17 +0000</pubDate>
		<dc:creator>Paulo Silveira</dc:creator>
				<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[BigDecimal]]></category>
		<category><![CDATA[ddd]]></category>
		<category><![CDATA[double]]></category>
		<category><![CDATA[floating point]]></category>
		<category><![CDATA[fluent interface]]></category>
		<category><![CDATA[ieee 754]]></category>
		<category><![CDATA[imutabilidade]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=2905</guid>
		<description><![CDATA[É fácil se deparar com as limitações do double no Java e na maioria das outras linguagens: quando vamos trabalhar com dinheiro notamos que as contas não estão saindo exatamente como esperávamos:

double d1 = 0.1;
double d2 = 0.2;
System.out.println(d1 + d2);

O resultado é um estranho 0.30000000000000004, que pode acarretar em problemas graves dependendo da utilização e [...]]]></description>
			<content:encoded><![CDATA[<p>É fácil se deparar com as limitações do <code>double</code> no Java e na maioria das outras linguagens: quando vamos trabalhar com dinheiro notamos que as contas não estão saindo exatamente como esperávamos:</p>
<pre class="brush: java;">
double d1 = 0.1;
double d2 = 0.2;
System.out.println(d1 + d2);
</pre>
<p>O resultado é um estranho <code>0.30000000000000004</code>, que pode acarretar em problemas graves dependendo da utilização e arrendondamento aplicado depois nesse número. O problema é que um número com <code>0.1</code> não pode ser representado em binário de maneira finita: ele vira uma dízima (no binário ficaria algo como <code>0.110011001100</code>&#8230;) diferente do número <code>0.25</code>, que pode ser representado perfeitamente (no binário <code>0.01</code>). A representação é um pouco mais complicada que isso, <a href="http://people.uncw.edu/tompkinsj/133/numbers/Reals.htm">a JVM segue o padrão</a> <a href="http://grouper.ieee.org/groups/754/">IEEE 754</a> para trabalhar com números de ponto flutuante.</p>
<p>Como obter o esperado <code>0.3</code>? A sugestão sempre é usar o <code><a href="http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/math/BigDecimal.html">BigDecimal</a></code>. <code>BigDecimal</code> é uma classe que trabalha com números de ponto flutuante de precisão arbitrária: você pode escolher quanto de precisão você quer usar. Por padrão ele vai utilizar o que for necessário, e, diferente do <code>double</code>, ele consegue guardar números como <code>0.1</code>, pois guardará isto como sendo <code>1 x 10ˆ-1</code> (isto é, usando a base decimal em vez de binária, evitando a dízima).</p>
<pre class="brush: java;">
// nao use esse construtor:
BigDecimal big1 = new BigDecimal(0.1);
BigDecimal big2 = new BigDecimal(0.2);

System.out.println(big1.add(big2));
</pre>
<p>O resultado é uma nova surpresa, um incrível <code>0.300000000000000016653345369377...</code>. O que fizemos de errado agora foi que tentar somar <code>0.1</code> e <code>0.2</code> sendo que esses dois números já estavam armazenados em memória como <code>double</code>, e, ao serem passados para o construtor do <code>BigDecimal</code>, foram transportados com imprecisão. O <a href="http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/math/BigDecimal.html#BigDecimal(double)">próprio javadoc desse construtor</a> diz que  &#8220;<em>The results of this constructor can be somewhat unpredictable</em>&#8220;. Na verdade o resultado é bem previsível pelas suas regras, mas não é o que gostaríamos. </p>
<p>Como resolver? Basta sempre usar o construtor que trabalha com <code>String</code>s, assim o <code>BigDecimal</code> vai internamente fazer o parsing desses números sem que eles sejam armazenados em um <code>double</code>, evitando os problemas de precisão:</p>
<pre class="brush: java;">
// atencao! usando String no construtor:
BigDecimal big1 = new BigDecimal(&quot;0.1&quot;);
BigDecimal big2 = new BigDecimal(&quot;0.2&quot;);

System.out.println(big1.add(big2));
</pre>
<p>Finalmente obtendo o resultado esperado. Há ainda importantes observações sobre o <code>BigDecimal</code>: por padrão ele não fará nenhum tipo de arredondamento, o que o obriga a lançar  <code>java.lang.ArithmeticException</code> no caso de uma dízima decimal (tentar dividir 1/3 por exemplo). Nesses casos é necessário delimitar a quantidade de bits a serem usados ou escolher <a href="http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/math/RoundingMode.html">o modo de arredondamento</a>:</p>
<pre class="brush: java;">
BigDecimal big1 = new BigDecimal(&quot;1&quot;);
BigDecimal big2 = new BigDecimal(&quot;3&quot;);

System.out.println(big1.divide(big2, 3, RoundingMode.UP));
</pre>
<p>Resultando em <code>0.334</code>. Vale lembrar também da imutabilidade da classe <code>BigDecimal</code>, que traz diversas vantagens mas deve ser usada com cuidado quando diversas operações serão realizadas em cima de um mesmo número dentro de um laço, já que diversos <code>BigDecimal</code>s serão instanciados durante a operação, podendo acarretar no mesmo <a href="http://blog.caelum.com.br/2010/06/13/revisitando-a-concatenacao-de-strings-stringbuilder-e-stringbuffer/">problema de performance do uso de concatenação de Strings</a>. O Donizetti lembrou que esse assunto é bastante discutido no item 48 do <a href="http://blog.caelum.com.br/2008/07/25/effective-java-segunda-edicao/">Effective Java</a>.</p>
<p>No JavaScript teremos o mesmo problema caso você precise realizar contas no lado do cliente, e aí podemos usar a <a href="http://github.com/jhs/bigdecimal.js/">BigDecimalJS</a>, <a href="http://jefferson.eti.br/tech/">sugerida pelo Jefferson Girão</a>, que funciona de maneira análoga ao Java.</p>
<p>O <a href="http://blog.rafaelferreira.net/">Rafael Ferreira</a> lembra que podemos ir além, e como dinheiro é algo pertencente ao nosso domínio e lógica de negócios, criamos uma classe <code>Money</code> para encapsular todo esse comportamento e evitar que <code>RoundingMode</code>, <code>MathContext</code> e escalas se espalhem por todo seu código.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fblog.caelum.com.br%2F2010%2F07%2F15%2Farredondamento-no-java-do-double-ao-bigdecimal%2F&amp;linkname=Arredondamento%20no%20Java%3A%20do%20double%20ao%20BigDecimal"><img src="http://blog.caelum.com.br/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/2010/07/15/arredondamento-no-java-do-double-ao-bigdecimal/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Prática ágil: facilite a comunicação interna</title>
		<link>http://blog.caelum.com.br/2010/07/13/pratica-agil-facilite-a-comunicacao-interna/</link>
		<comments>http://blog.caelum.com.br/2010/07/13/pratica-agil-facilite-a-comunicacao-interna/#comments</comments>
		<pubDate>Tue, 13 Jul 2010 22:27:11 +0000</pubDate>
		<dc:creator>Guilherme Silveira</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[práticas]]></category>
		<category><![CDATA[agilidade]]></category>
		<category><![CDATA[Ágil]]></category>
		<category><![CDATA[comunicação]]></category>
		<category><![CDATA[feedback]]></category>
		<category><![CDATA[prática]]></category>
		<category><![CDATA[product owner]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=2871</guid>
		<description><![CDATA[Sintoma: durante o processo de desenvolvimento de uma funcionalidade, a equipe se direciona ao Product Owner ou cliente para tirar dúvidas, mas o mesmo se encontra frequentemente ocupado e não pode responder. Quando o PO está livre, a equipe está concentrada em outra tarefa.
Ação: crie uma lista de discussão envolvendo todos os interessados no projeto [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Sintoma</strong>: durante o processo de desenvolvimento de uma funcionalidade, a equipe se direciona ao Product Owner ou cliente para tirar dúvidas, mas o mesmo se encontra frequentemente ocupado e não pode responder. Quando o PO está livre, a equipe está concentrada em outra tarefa.</p>
<p><strong>Ação</strong>: crie uma lista de discussão envolvendo todos os interessados no projeto (Product Owner, desenvolvedores, <a href="http://blog.caelum.com.br/2010/01/29/html-css-javascript-e-ux-na-nova-formacao-da-caelum/">User Experience</a>, clientes envolvidos com aceitação etc) e envie um email para a lista.</p>
<p>Deixamos de lado a antiga &#8220;pastelaria&#8221; que exigia disponibilidade dos desenvolvedores no exato instante do aparecimento de uma necessidade, tudo era &#8220;para agora&#8221;. O mesmo vale para o Product Owner e qualquer outro ser humano em seu trabalho.</p>
<p><a href="http://agilediary.wordpress.com/2009/10/19/product-vision-the-key-role-responsibility-of-product-owner/">Apesar de muito desejado</a>, é impossível exigir que no exato instante que surge uma dúvida da equipe de desenvolvimento, o Product Owner esteja disponível para conversar.</p>
<p>Vale lembrar que o email é uma comunicação assíncrona que leva mais tempo para obter resultados, além de ter chances de ser mal compreendido, portanto a primeira maneira a ser abordada para resolver um problema deve ser sempre a cara a cara com o PO.</p>
<p><center><div id="attachment_2874" class="wp-caption alignnone" style="width: 417px"><a href="http://blog.caelum.com.br/wp-content/uploads/2010/07/onde_trabalhar.png"><img class="size-full wp-image-2874" title="onde_trabalhar" src="http://blog.caelum.com.br/wp-content/uploads/2010/07/onde_trabalhar.png" alt="Lista de discussão de um projeto/produto" width="407" height="176" /></a><p class="wp-caption-text">Lista de discussão de um projeto/produto. Criar uma lista de discussão leva 2 minutos e permite receber feedback da primeira pessoa disponível, além de facilitar a busca por conversas quando novos membros entrarem.</p></div></center></p>
<p>Como o problema é a escassez de tempo de um indíviduo específico do qual esperamos uma resposta, o envio para uma lista que envolve PO, UX e clientes diminui o tempo no escuro, sem feedback. Para evitar uma discussão, faça perguntas diretas que esperam respostas fechadas, por exemplo:</p>
<blockquote><p>
Bom dia,</p>
<p>Estamos com uma dúvida em relação a listagem de contas atrasadas.<br />
As com mais de um mês de atraso devem aparecer com outra cor,<br />
conforme o padrão da tela de faturas?</p>
<p>Nesse caso um mês é considerado 30 dias, correto? Ou precisamos ter precisão de dias de acordo com o mês?
</p></blockquote>
<p>Caso a pergunta enviada seja um pedido de aprovação de história, inicie a próxima história até receber o feedback da mesma:</p>
<blockquote><p>Bom dia,</p>
<p>As histórias A e B foram finalizadas e estão aguardando aprovação.
</p></blockquote>
<p>Caso a pergunta permanença em aberto sem resposta mesmo após o envio de um email, procure a conversa pessoal novamente: também é nosso papel como desenvolvedor conseguir a resposta, removendo impedimentos.</p>
<p>Veja também: <a href="http://blog.caelum.com.br/2010/07/07/pratica-prefira-terminar-a-comecar-outra-historia/">prefira terminar a começar outra história</a>.</p>
<p><!-- Ver também: limite o trabalho em progresso, quando tempo eh escasso, aprove com o cliente --></p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fblog.caelum.com.br%2F2010%2F07%2F13%2Fpratica-agil-facilite-a-comunicacao-interna%2F&amp;linkname=Pr%C3%A1tica%20%C3%A1gil%3A%20facilite%20a%20comunica%C3%A7%C3%A3o%20interna"><img src="http://blog.caelum.com.br/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/2010/07/13/pratica-agil-facilite-a-comunicacao-interna/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
