<?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 &#187; design</title>
	<atom:link href="http://blog.caelum.com.br/tag/design/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.caelum.com.br</link>
	<description>blog dos desenvolvedores da Caelum</description>
	<lastBuildDate>Thu, 09 Feb 2012 13:04:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Lançamento do livro Introdução à Arquitetura e Design de Software</title>
		<link>http://blog.caelum.com.br/lancamento-do-livro-introducao-a-arquitetura-e-design-de-software/</link>
		<comments>http://blog.caelum.com.br/lancamento-do-livro-introducao-a-arquitetura-e-design-de-software/#comments</comments>
		<pubDate>Thu, 15 Dec 2011 18:07:39 +0000</pubDate>
		<dc:creator>Paulo Silveira</dc:creator>
				<category><![CDATA[Arquitetura]]></category>
		<category><![CDATA[Caelum]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[fj-16]]></category>
		<category><![CDATA[fj-91]]></category>
		<category><![CDATA[fj-95]]></category>
		<category><![CDATA[livro]]></category>
		<category><![CDATA[patterns]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=4662</guid>
		<description><![CDATA[Depois de uma longa espera, temos o tão aguardado lançamento. O livro está sendo distribuído para as livrarias, e já é bem fácil encontrá-lo nas lojas online, como na Saraiva. Foi bastante tempo e trabalho para criar uma introdução abrangente, e ao mesmo tempo com uma necessária profundidade, de alguns dos principais tópicos da plataforma <a href="http://blog.caelum.com.br/lancamento-do-livro-introducao-a-arquitetura-e-design-de-software/#more-4662'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/capa_Arquitetura-e-Design-de-Software.jpg" width="240" />
		</p><p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/capa_Arquitetura-e-Design-de-Software.jpg"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/capa_Arquitetura-e-Design-de-Software-211x300.jpg" alt="" title="capa_Arquitetura e Design de Software" width="211" height="300" class="alignleft size-medium wp-image-4678" /></a> Depois de uma longa espera, temos o tão aguardado lançamento. O livro está sendo distribuído para as livrarias, e já é bem fácil encontrá-lo nas lojas online, <a href="http://www.livrariasaraiva.com.br/produto/3705598/introducao-a-arquitetura-e-design-de-software-uma-visao-sobre-a-plataforma-java/">como na Saraiva</a>.</p>
<p>Foi bastante tempo e trabalho para criar uma introdução abrangente, e ao mesmo tempo com uma necessária profundidade, de alguns dos principais tópicos da plataforma Java. Em vez de apresentar respostas e fórmulas prontas, procuramos colocar questões para que os trade-offs tornem-se bem visíveis. Passamos por detalhes da JVM e design de classes até uso de frameworks, serviços, testes e automação.</p>
<p>Você pode encontrar detalhes do livro, conteúdo, além de algumas seções para ler no <a href="http://www.arquiteturajava.com.br/">site oficial</a>.</p>
<p>Haverá uma confraternização em São Paulo, dia 26 de janeiro, às 19h00, na Saraiva do Shopping Paulista, comemorando o lançamento do livro. Você está convidado!</p>
<p>Esperamos que aproveite nosso trabalho, e agradecemos a todos alunos, desenvolvedores e instrutores que possibilitaram essa realização.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/lancamento-do-livro-introducao-a-arquitetura-e-design-de-software/feed/</wfw:commentRss>
		<slash:comments>43</slash:comments>
		</item>
		<item>
		<title>Adequar o banco às entidades ou o contrário?</title>
		<link>http://blog.caelum.com.br/adequar-o-banco-as-entidades-ou-o-contrario/</link>
		<comments>http://blog.caelum.com.br/adequar-o-banco-as-entidades-ou-o-contrario/#comments</comments>
		<pubDate>Tue, 09 Aug 2011 13:37:37 +0000</pubDate>
		<dc:creator>Erich Egert</dc:creator>
				<category><![CDATA[Arquitetura]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[banco de dados]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[embeddable]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[jpa]]></category>
		<category><![CDATA[mapeamento]]></category>
		<category><![CDATA[orm]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=4515</guid>
		<description><![CDATA[Uma das features interessantes do Hibernate é gerar a Data Definition Language para criação da estrutura de tabelas do banco de dados (schema). Tudo que precisamos fazer é pensar em nosso modelo Orientado a Objeto que o banco é gerado automaticamente a partir das entidades. Aparentemente o processo de pensar na modelagem do banco de <a href="http://blog.caelum.com.br/adequar-o-banco-as-entidades-ou-o-contrario/#more-4515'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/08/database-application.jpg" width="240" />
		</p><p>Uma das features interessantes do <a title="Hibernate" href="http://www.hibernate.org/">Hibernate</a> é gerar a <a title="Data Definition Language" href="http://en.wikipedia.org/wiki/Data_Definition_Language">Data Definition Language</a> para criação da estrutura de tabelas do banco de dados (schema). Tudo que precisamos fazer é pensar em nosso modelo Orientado a Objeto que o banco é gerado automaticamente a partir das entidades. Aparentemente o processo de pensar na modelagem do banco de dados tornou-se obsoleto: é aí que mora o perigo.</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/08/database-application.jpg"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/08/database-application.jpg" alt="mapeamento de banco de dados a orientacao a objetos" title="database-application" width="400" height="300" class="aligncenter size-full wp-image-4518" /></a></p>
<p>Na orientação a objetos é preferível favorecer especialização através da divisão de responsabilidades. Em vez de criar uma classe gigantesca devemos quebrá-la em pequenas classes.</p>
<p>Quando o assunto é banco de dados a análise é bem diferente. No modelo relacional, a preocupação é normalização dos dados e a modelagem ao mesmo tempo tende a ser pensada de forma a evitar a necessidade de alguns joins que seriam mais caros. Muitas vezes é preferível criar uma tabela com várias colunas com todas as informações pertinentes a criar várias tabelas especializadas. Para ilustrar, considere as entidades:</p>
<pre class="brush: java; title: ; notranslate">
@Entity
public class Produto {
  @Id
  @GeneratedValue
  private Long id;
  private String nome;
  private BigDecimal preco;
  private Calendar inicioPeriodoPromocional;
  private Calendar fimPeriodoPromocional;
  // outros atributos e metodos
}

@Entity
public class Promocao {
 private Calendar inicio;
 private Calendar fim;
 //outros atributos e metodos
}
</pre>
<p>Suponha que gostaríamos de saber se uma promoção é aplicável a um produto e por quantos dias podemos aproveitar uma promoção. Colocar esse código dentro de um controller ou managed bean não parece uma boa idéia. Esse trecho rapidamente reaparecerá em outro lugar. Onde então podemos criar métodos para essa análise? Poderíamos começar criando a classe <code>Intervalo</code>:</p>
<pre class="brush: java; title: ; notranslate">
public class Intervalo {
  private Calendar inicio;
  private Calendar fim;
}
</pre>
<p>E em vez de <code>Produto</code> e <code>Promocao</code> guardarem referências para duas datas, guardariam para um <code>Intervalo</code>, removendo os respectivos <code>Calendars</code>:</p>
<pre class="brush: java; title: ; notranslate">
@Entity
public class Produto {
  @Id
  @GeneratedValue
  private Long id;
  private String nome;
  private BigDecimal preco;
  private Intervalo periodoPromocional;
  //...
}

@Entity
public class Promocao {
  private Intervalo vigencia;
  //...
}
</pre>
<p>A criação da classe <code>Intervalo</code> pode trazer benefícios muito maiores do que a eliminação da repetição de atributos. Adotando a boa prática de unir dados a comportamentos, podemos isolar todo comportamento relacionado a um intervalo de datas nessa nova classe:</p>
<pre class="brush: java; title: ; notranslate">
public class Intervalo {
  private Calendar inicio;
  private Calendar fim;

  public int getDias() {...}
  public Intervalo interseccaoCom(Intervalo outro) {...}
}
</pre>
<p>Para saber quantos dias temos para aproveitar a promoção faríamos:</p>
<pre class="brush: java; title: ; notranslate">
Intervalo janelaDeOportunidade =
  produto.getPeriodoPromocional().interseccaoCom(promocao.getVigencia());

int diasParaAproveitar = janelaDeOportunidade.getDias();
</pre>
<p>Mas como mapeamos a classe <code>Intervalo</code>? Criar uma tabela e referenciar seus registros através de chaves estrangeiras nas tabelas <code>Produto</code> e <code>Promocao</code> só trará a necessidade de joins. A JPA nos oferece uma alternativa: criar uma classe <code>Embeddable</code>, um dos assuntos básicos abordados no <a title="FJ-25 Persistência com JPA2 e Hibernate" href="http://www.caelum.com.br/curso/fj-25-persistencia-jpa2-hibernate/">FJ-25</a>. Quando anotamos uma classe com <code>@Embeddable</code>, seus atributos serão colunas na tabela da entidade que tem o atributo anotado com <code>@Embedded</code>.</p>
<pre class="brush: java; title: ; notranslate">
@Embeddable
public class Intervalo {
  //...
}

@Entity
public class Promocao {
  @Embedded
  private Intervalo vigencia;
  // a tabela Promocao terá uma coluna inicio e outra fim
  // ...
}
</pre>
<p>A classe <code>Intervalo</code> não precisa de um identificador único: ela é definida pelo seu valor e pode ser encarada como um <a title="Value Object" href="http://martinfowler.com/bliki/ValueObject.html">Value Object</a>. É importante conhecer os diversos recursos do Hibernate que nos dão a possibilidade de não precisar adequar nossas entidades às nossas tabelas, nem de adequar nossas tabelas às nossas entidades. Por exemplo, tabelas secundárias oferecem o serviço inverso: uma entidade mapeada em duas tabelas. O próprio <code>@ManyToMany</code> evita a criação de uma classe a mais apenas para manter referências para as duas classes relacionadas. Há ainda o suporte a chaves compostas, herança, nomenclatura das tabelas, namespaces e colunas, e até mesmo tipos definidos pelo próprio usuário para cada banco de dados diferente.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/adequar-o-banco-as-entidades-ou-o-contrario/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Scala: os cuidados com encapsulamento</title>
		<link>http://blog.caelum.com.br/scala-os-cuidados-com-encapsulamento/</link>
		<comments>http://blog.caelum.com.br/scala-os-cuidados-com-encapsulamento/#comments</comments>
		<pubDate>Tue, 26 Jul 2011 11:00:46 +0000</pubDate>
		<dc:creator>Guilherme Silveira</dc:creator>
				<category><![CDATA[Inovação]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[encapsulamento]]></category>
		<category><![CDATA[good citizen]]></category>
		<category><![CDATA[oo]]></category>
		<category><![CDATA[orientação a objetos]]></category>
		<category><![CDATA[Qualidade]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=4469</guid>
		<description><![CDATA[Um dos pontos difíceis de lidar em qualquer sistema está ligado com quebra de encapsulamento. Em Java, uma vez que o padrão de uma variável membro permite que ela seja acessada por fora do objeto, protegemos os dados através do modificador private e um getter: Enquanto a criação de getters é um padrão amplamente adotado, <a href="http://blog.caelum.com.br/scala-os-cuidados-com-encapsulamento/#more-4469'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/07/235948470_38c8994d9d_z.jpg" width="240" />
		</p><p>Um dos pontos difíceis de lidar em qualquer sistema está ligado com <a href="http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod">quebra de encapsulamento</a>. Em Java, uma vez que o padrão de uma variável membro permite que ela seja acessada por fora do objeto, protegemos os dados através do modificador <code>private</code> e um getter:</p>
<pre class="brush: java; title: ; notranslate">
public class Conta {
  private List&lt;Movimentacao&gt; movimentacoes = new ArrayList&lt;Movimentacao&gt;();
  private double saldo;

  public double getSaldo() {
    return saldo;
  }

  public List&lt;Movimentacao&gt; getMovimentacoes() {
    return movimentacoes;
  }
}
</pre>
<p>Enquanto a criação de getters é um padrão amplamente adotado, muitas vezes ainda deixamos vazar os objetos mutáveis, como no caso da lista acima. Para não vazar referências a tais objetos, quebrando o encapsulamento e possívelmente alguma funcionalidade interna, retornamos uma cópia segura da mesma:</p>
<pre class="brush: java; title: ; notranslate">
  public List&lt;Movimentacao&gt; getMovimentacoes() {
    // protegendo a lista interna para não quebrar o encapsulamento
    return Collections.unmodifiableList(movimentacoes);
  }
</pre>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/07/235948470_38c8994d9d_z.jpg"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/07/235948470_38c8994d9d_z-300x200.jpg" alt="http://www.flickr.com/photos/fxtreme/235948470/" title="235948470_38c8994d9d_z" width="300" height="200" class="alignleft size-medium wp-image-4507" /></a><br />
<a href="http://blog.caelum.com.br/nao-aprender-oo-getters-e-setters/">A criação de getters e setters deve ser feita com cuidado</a>: uma vez que a implementação é exposta através de um getter e setter, a remoção dele, para finalmente encapsulá-lo, implica na mudança de todas as chamadas a ele. Em Ruby, o mesmo cuidado pode ser tomado:</p>
<pre class="brush: ruby; title: ; notranslate">
class Conta
  def movimentacoes
    @movimentacoes.dup
  end
end
</pre>
<p>Em Scala, existem diversas variações para declaração de variáveis membro. A padrão que ainda <a href="http://docs.codehaus.org/display/PICO/Good+Citizen">nos ajuda a criar good citizens</a>, é a definição de uma variável privada, final:</p>
<pre class="brush: java; title: ; notranslate">
class Conta(saldo:Double)
</pre>
<p>A desvantagem é que as vezes é interessante colocar um getter para expor o conteúdo referenciado. No caso de uma conta bancária, é interessante expor o saldo da mesmo, mas não uma lista de movimentações sem protegê-la.</p>
<p>Para isso, podemos definir uma <code>val</code> (equivalente a variáveis final em Java), uma vez que o papel do getter é gerado automaticamente pelo compilador (nomes de variáveis e métodos estão no mesmo contexto, portanto não requerem recompilação quando um substitui o outro):</p>
<pre class="brush: java; title: ; notranslate">
class Conta(val saldo:Double)
</pre>
<p>A desvantagem pode estar em desejar alterar o saldo da conta e não poder. Nesse caso definiríamos o membro como <code>var</code>:</p>
<pre class="brush: java; title: ; notranslate">
class Conta(var saldo:Double)
</pre>
<p>A desvantagem nessa abordagem é a criação do getter e do setter de exposição: ao definir uma variável como &#8220;private&#8221; mas permitir o acesso a mesma, o encapsulamento é novamente quebrado. Portanto, para membros cuja referência pode ser alterada (vars), é interessante gerar o &#8220;getter&#8221; mas não expor o setter para não quebrar o encapsulamento, como em: </p>
<pre class="brush: java; title: ; notranslate">
class Conta(private var _saldo:Double) {
  def saldo = _saldo
}
</pre>
<p>Mas nesse caso, o código deixa de ser curto como nas abordagens onde o encapsulamento é mais facilmente quebrado. O mesmo é válido para muitas linguagens: é mais fácil quebrar o encapsulamento dos objetos do que executar a troca de mensagens para efetuar uma transferência:</p>
<pre class="brush: java; title: ; notranslate">
class Conta(private var _saldo:Double) {
  def saldo = _saldo
  def debita(valor:Double) {
    movimentacoes.add(new Movimentacao(-valor));
    _saldo -= valor
  }
}
</pre>
<p>O encapsulamento é a base de orientação a objetos. Nos momentos em que é adequado trabalhar de forma OO, é ele que <a href="http://pragprog.com/articles/tell-dont-ask">permite a troca de mensagens entre objetos</a> prevenindo o usuário de depender de como o tipo funciona internamente. Das maneiras demonstradas aqui, escolha a maneira de encapsular suficientemente adequada para faciltiar a manutenção de suas classes a longo prazo (para evitar quebras inesperadas). </p>
<p>Como pergunta, será que seria interessante a linguagem fornecer uma opcao só de getter para var?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/scala-os-cuidados-com-encapsulamento/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>TDD e sua influência no acoplamento e coesão</title>
		<link>http://blog.caelum.com.br/tdd-e-sua-influencia-no-acoplamento-e-coesao/</link>
		<comments>http://blog.caelum.com.br/tdd-e-sua-influencia-no-acoplamento-e-coesao/#comments</comments>
		<pubDate>Thu, 17 Feb 2011 15:14:13 +0000</pubDate>
		<dc:creator>Guilherme Silveira</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Arquitetura]]></category>
		<category><![CDATA[Inovação]]></category>
		<category><![CDATA[acoplamento]]></category>
		<category><![CDATA[agilidade]]></category>
		<category><![CDATA[coesão]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[design evolutivo]]></category>
		<category><![CDATA[feedback]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[testes de unidade]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=4116</guid>
		<description><![CDATA[Escrever testes de unidade é uma prática cada vez mais adotada. Ela ajuda a verificar se tudo funciona como o esperado mesmo após mudanças, trazendo mais segurança para a equipe ao alterar o código. Mas os testes de unidade vão além, possibilitando a validação de um design. Um código fácil de testar tende a apresentar um bom design. <a href="http://blog.caelum.com.br/tdd-e-sua-influencia-no-acoplamento-e-coesao/#more-4116'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/02/tdd.jpg" width="240" />
		</p><p>Escrever testes de unidade é uma prática cada vez mais adotada. Ela  ajuda a verificar se tudo funciona como o esperado mesmo após mudanças, trazendo mais segurança para a equipe ao alterar o código. Mas os testes de unidade vão além, <strong>possibilitando a validação de um design</strong>.</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/02/tdd.jpg"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/02/tdd-300x186.jpg" alt="" title="tdd" width="300" height="186" class="aligncenter size-medium wp-image-4120" /></a></p>
<p>Um código fácil de testar tende a apresentar um bom design. <em><a href="http://michaelfeathers.typepad.com/michael_feathers_blog/2007/09/the-deep-synerg.html">Existe uma grande sinergia entre testabilidade e um bom design</a></em>. Isso acontece pois, para que o programador consiga testar uma classe de maneira isolada e facilmente, essa classe deve lidar muito bem com suas dependências (buscando sempre um baixo acoplamento) e possuir pouca responsabilidade (ou seja, ser altamente coesa). Caso contrário, o programador gastará muito tempo tentando testá-la, um possível indicador de que a classe apresenta um design pobre.</p>
<p>Um design que apresenta classes com alto acoplamento são difíceis de testar, surgindo a necessidade de passar as dependências para nossos objetos e só então testá-los.</p>
<p>O primeiro resultado ao adicionar testes de unidade a um sistema é a mudança de padrões imperativos de execução onde instanciamos objetos e invocamos métodos para a injeção de dependências.</p>
<p>O exemplo a seguir mostra um processador sendo instanciado, o que torna difícil verificar se o comportamento do <code>ExecutorDeBatch </code> foi correto sem executar o código da classe <code>Processador</code>:</p>
<pre class="brush: java; title: ; notranslate">
public class ExecutorDeBatch {
  public void le(ListaDeItens itens) {
    Processador processador = new Processador();
    while(itens.temProximo()) {
       String item = sc.proximo();
       processador.interpreta(item);
    }
  }
}
</pre>
<p>O teste acima verifica o comportamento do <code>ExecutorDeBatch</code> junto com o <code>Processador</code>. Esse tipo de teste é considerado de integração, não passando muita informação sobre o acoplamento entre as classes, mas somente garantindo o comportamento em conjunto. </p>
<p>Para isolar a classe acima seria necessário a utilização de um <a href="http://blog.caelum.com.br/testes-unitarios-com-jmock-2/">mock</a> no lugar do <code>Processador</code>. Da maneira que o código está, seria bastante trabalhoso. No Java exigiria até manipulação de bytecode durante o classload para que fosse possível alterar a classe instanciada no momento do <code>new Processador()</code> por exemplo. Para isso, o programador deve deixar essas dependências bem explícitas, recebendo-as através do construtor, por exemplo. Teríamos então o seguinte código:</p>
<pre class="brush: java; title: ; notranslate">
public class ExecutorDeBatch {
  private Processador processador;
  public ExecutorDeBatch(Processador processador) {
    this.processador = processador;
  }

  public void le(ListaDeItens itens) {
    while(itens.temProximo()) {
       String item = sc.proximo();
       processador.interpreta(item);
    }
  }
}
</pre>
<p>Passar um mock para a classe acima e consequentemente testá-la de maneira isolada ficou é fácil. A adoção dos testes de unidade deixa explícito o excesso de  dependências (ou dependências implícitas escondidas). </p>
<p>Por fim, os testes precisam ser simples e curtos, limitando seu escopo; um teste muito grande ou complicado <a href="http://www.amazon.com/Growing-Object-Oriented-Software-Guided-Tests/dp/0321503627">pode indicar que o método em questão possui muita responsabilidade</a>.</p>
<p>Considere uma classe que é responsável por gerar uma nota fiscal a partir de uma fatura e disparar a mesma para o e-mail do cliente, assim como para um sistema SAP qualquer. Essa classe já possui as dependências bem explícitas:</p>
<pre class="brush: java; title: ; notranslate">
public class GeradorDeNotaFiscal {
       private final Sap sap;
       private final EnviadorDeEmails enviador;

       public GeradorDeNotaFiscal(Sap sap, EnviadorDeEmails enviador) {
               this.sap = sap;
               this.enviador = enviador;
       }

       private NotaFiscal geraNotaFiscalAPartirDa(Fatura fatura) {
           // codigo de geracao da nota fiscal
       }

       public void gera(Fatura fatura) {
               NotaFiscal nf = geraNotaFiscalAPartirDa(fatura);

               sap.armazena(nf);
               enviador.envia(nf);
       }
}
</pre>
<p>Passar mocks para essa classe é fácil, já que é possível injetar todas as dependências nela. O problema é que, para criar testes para ela, o programador se preocuparia em testar se a nota fiscal foi gerada, se ela é enviada ao SAP e se ela é enviada para o cliente:</p>
<pre class="brush: java; title: ; notranslate">
@Test public void deveGerarANf() { ... }
@Test public void deveArmazenarNfNoSap() { ... }
@Test public void deveEnviarNfParaOEmailDoCliente() { ... }
</pre>
<p>Perceba que essa classe tem responsabilidades demais: ela gera NF, envia para o SAP, envia para o cliente. Ao escrever esses testes, o programador perceberia que, em cada teste, ele estaria preocupado em testar uma responsabilidade da classe, sem se importar com a outra. No teste <code>deveArmazenarNfNoSap</code>, por exemplo, o programador seria obrigado a passar um stub da classe <code>Email</code>, mesmo não sendo o foco daquele teste. Isso torna a escrita do teste mais massante é um sinal de que a classe tem baixa coesão.</p>
<p>Portanto, se o seu design possue um alto acoplamento ou uma baixa coesão, será praticamente impossível escrever testes de unidade. Por esse mesmo motivo métodos estáticos, singletons, factories e estado global dificultam os testes de unidade.</p>
<p>Pensar e criar os testes antes do código também auxiliam no design. Usar <a href="http://www.amazon.com/Test-Driven-Development-Kent-Beck/dp/0321146530">Test-Driven Development</a> força que a concentração do pensamento lógico foque nas responsabilidades de cada método, ao invés da exata implementação do mesmo.</p>
<p>Esse impacto no design é tão grande que muitos <a href="http://www.agiledata.org/essays/tdd.html">vão utilizar a sigla TDD para Test-Driven Design</a>. Com TDD o programador é forçado a pensar em decisões de design antes do código de implementação, criando um maior desacoplamento, <a href="http://athenea.ort.edu.uy/publicaciones/ingsoft/recursos/articulos/AimFire.pdf">deixando mais claro suas necessidades</a>.</p>
<p>O TDD, através dos testes de unidade e refatoração, possibilitam que o <a href="http://martinfowler.com/articles/designDead.html">design apareça de uma maneira mais evolutiva</a>, mas sem mágicas, sempre dependendo de conhecimento do desenvolvedor em relação a design e orientação a objetos.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/tdd-e-sua-influencia-no-acoplamento-e-coesao/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Perdendo ou ganhando tempo com testes de unidade</title>
		<link>http://blog.caelum.com.br/perdendo-ou-ganhando-tempo-com-testes-de-unidade/</link>
		<comments>http://blog.caelum.com.br/perdendo-ou-ganhando-tempo-com-testes-de-unidade/#comments</comments>
		<pubDate>Fri, 10 Dec 2010 15:06:22 +0000</pubDate>
		<dc:creator>Mauricio Aniche</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[acoplamento]]></category>
		<category><![CDATA[agilidade]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[design pattern]]></category>
		<category><![CDATA[ioc]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[pm-87]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[teste]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=3588</guid>
		<description><![CDATA[Durante as aulas e palestras sobre TDD e testes de software é bem comum ouvir perguntas relativas a &#8220;o que deve ser testado e o que não precisa ser testado&#8221;. Geralmente os exemplos inicials que encontramos na literatura sobre TDD são muito simplistas, nos levando a crer que devemos testar todo e qualquer método de <a href="http://blog.caelum.com.br/perdendo-ou-ganhando-tempo-com-testes-de-unidade/#more-3588'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.caelum.com.br/curso/pm-87-agile-praticas-ageis/">Durante as aulas e palestras sobre TDD e testes de software</a> é bem comum ouvir perguntas relativas a &#8220;o que deve ser testado e o que não precisa ser testado&#8221;.  Geralmente os exemplos inicials  que encontramos na literatura sobre TDD são muito simplistas, nos levando a crer que devemos testar todo e qualquer método de uma classe de maneira isolada, mesmo que não faça muito sentido.</p>
<p>Um exemplo desse tipo de abordagem é a tentativa de se testar uma constante, entre outros clássicos como a presença de uma anotação, métodos de delegação, getters e setters, etc. Supondo uma classe que armazena constantes de cartão de crédito e um possível teste de unidade para ela:</p>
<pre class="brush: java; title: ; notranslate">
public class CartoesDeCreditoTest {
  @Test
  public void deveRelacionarVisaComOValor123() {
    assertEquals(123, CartoesDeCredito.VISA);
  }
}

public class CartoesDeCredito {
  public final static int VISA = 123;
  public final static int MASTERCARD = 456;
}
</pre>
<p>Repare que existe uma duplicação de dados entre o código de teste e o código de produção: o número <em>123</em>. Quando o valor dessa constante mudar, você possui dois pontos de código para alterar. Ao fazer uma refatoração para remover essa duplicação, teremos um resultado como a seguir:</p>
<pre class="brush: java; title: ; notranslate">
public class CartoesDeCreditoTest {
  @Test
  public void deveRelacionarVisaComOValor123() {
    assertEquals(CartoesDeCredito.VISA, CartoesDeCredito.VISA);
  }
}
</pre>
<p>Muitas vezes, o programador, acostumado a escrever testes de unidade para todo o código, acaba desenvolvendo testes sem utilidade: código que na realidade não testa nada. Naturalmente, o desenvolvedor não faria a refatoração acima, tal exemplo demonstra como um teste do genêro não traz valor, somente complexidade para nosso sistema.</p>
<p>Ou seja, em casos como o mostrado acima não há utilidade em escrever um teste de unidade para constantes. Ao fazer isso, o programador gera <a href="http://www.amazon.com/Test-Driven-Development-Kent-Beck/dp/0321146530/ref=sr_1_1?ie=UTF8&amp;qid=1290727199&amp;sr=8-1">duplicação de dados entre a classe de teste e a de produção</a>.</p>
<p>É importante testar constantes, mas no caso acima por exemplo, <strong>não através de testes de unidade</strong>: se ela representa um valor de um outro sistema, por exemplo, escreva um teste de integração.</p>
<p>No caso do cartão de crédito, suponha que a constante 123 seja o código do pagamento via cartão VISA no sistema do PayPal, portanto testamos a integração entre a aplicação e o sistema externo. Verifique se, ao passar o valor 123, o pagamento gerado foi um pagamento VISA.</p>
<pre class="brush: java; title: ; notranslate">
@Test
public void deveEnviarCartaoVisaParaOPayPal() {
  Cobranca resultado = payPal.efetuaCobranca(valor, numeroDeUmCartaoVisa, CartoesDeCredito.VISA);

  assert(that(resultado.getStatus()).is(PayPal.APROVADO));
}
</pre>
<p>Em um exemplo mais elaborado, imagine agora o seguinte trecho de código abaixo que usa o Active Record do Rails para fazer um filtro:</p>
<pre class="brush: ruby; title: ; notranslate">
def filtro(name)
  where(&quot;nome like %#{name}%&quot;)
end

def test_verifica_se_where_foi_invocado
  componente.should_receive(:where).with(&quot;nome like 'guilherme'&quot;)
  componente.filtro(&quot;guilherme&quot;)
end

# outra variação do mesmo teste:

def test_verifica_se_where_foi_invocado
  query = componente.filtro(&quot;guilherme&quot;)
  query[0].should == &quot;nome like 'guilherme'&quot;
end
</pre>
<p>Neste caso, uma vez que o método possui um corpo simples, uma invocação de uma função do Active Record, o teste abusa de <em>mocks</em> e é apenas uma mímica daquilo que o método executou. <strong>Ele garante somente que o programador digitou aquilo que ele esperava digitar.</strong> Testes como esse só indicam um problema no design do teste ou um problema no design do código.</p>
<p>No mundo Java é comum ver similares quando encontramos a utilização de Mocks ao extremo:</p>
<pre class="brush: java; title: ; notranslate">
public void adiciona(Produto p) {
  this.session.save(p);
}

@Test
public void testSalvarEhInvocado() {
  Produto produto = new Produt();
  one(session).save(produto);
  dao.adiciona(produto);
}
</pre>
<p>Veja que o próprio nome do método diz que ele não serve pra nada: <em>verifica se o salvar é invocado</em>. Você quer testar o comportamento que essa classe terá sobre seu sistema e não se um determinado método foi invocado. A obviedade que o método está sendo invocado é trivial de ser notada e por isso mesmo não precisaria ser nosso foco no teste.</p>
<p>Mas alguns podem dizer: <em>mas não preciso testar o Active Record, eu sei que ele funciona</em>. Ou ainda, <em>não preciso testar o Hibernate, eu sei que ele funciona</em>. Sim, você não precisa testar o Active Record unitariamente pois ele já foi testado, <strong>mas existe a necessidade de testar a integração do seu código com o Active Record.</strong> No exemplo de uma query, sabemos que escrevemos uma query como desejávamos, mas ela está retornando aquilo que desejamos? E deixando de lado o resto? São essas perguntas que nosso teste precisa responder.</p>
<pre class="brush: ruby; title: ; notranslate">
def test_deve_retornar_pessoas_que_tenham_parte_do_nome
  lista = executa_metodo_where(&quot;joão&quot;);

  lista.should_contain o_cidadao(&quot;João Gilberto&quot;)
end
</pre>
<p>O mesmo vale para queries em Java que utiliza JPA/Hibernate.</p>
<p><strong>Para saber mais sobre teste e design:</strong> Kent Beck já discutia acoplamento tanto de dados quanto de código entre classes de teste e classes de produção. Isso é muitas vezes ignorado pelo programador. Imagine que você precise alterar muitos testes toda vez que fizer uma pequena alteração: é um indício de um <a href="http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod">design rígido</a>, onde uma simples alteração propaga uma série de outras alterações.</p>
<blockquote><p>Como regra geral, que possui suas excecões, não existe valor em um teste que é uma mímica daquilo que foi <strong>digitado</strong> e não de seus efeitos e retornos. Nesse caso, pense duas vezes antes de escrever esse teste e verifique se testar aquela classe de outra maneira (através de um teste de integração, por exemplo) não seria mais útil.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/perdendo-ou-ganhando-tempo-com-testes-de-unidade/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Em busca do nome adequado: métodos, variáveis e classes</title>
		<link>http://blog.caelum.com.br/em-busca-do-nome-adequado-metodos-variaveis-e-classes/</link>
		<comments>http://blog.caelum.com.br/em-busca-do-nome-adequado-metodos-variaveis-e-classes/#comments</comments>
		<pubDate>Fri, 08 Oct 2010 17:42:09 +0000</pubDate>
		<dc:creator>Guilherme Silveira</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Arquitetura]]></category>
		<category><![CDATA[clean code]]></category>
		<category><![CDATA[ddd]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[domain driven design]]></category>
		<category><![CDATA[engenharia]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=3226</guid>
		<description><![CDATA[É muito comum após alguns dias de trabalho em um projeto perceber que as escolhas de nomes de classes e métodos não condizem com o que cada um representa. Isso acontece pois, com o passar do tempo, aumenta o nosso conhecimento sobre o domínio do problema. Também é natural surgir o desejo de mudança: a <a href="http://blog.caelum.com.br/em-busca-do-nome-adequado-metodos-variaveis-e-classes/#more-3226'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>É muito comum após alguns dias de trabalho em um projeto perceber que as escolhas de nomes de classes e métodos não condizem com o que cada um representa. Isso acontece pois, com o passar do tempo, aumenta o nosso conhecimento sobre o domínio do problema.</p>
<p>Também é natural surgir o desejo de mudança: <a href="http://fragmental.tw/2010/09/06/thoughts-on-abstractions-part-2-abstractions-in-your-domain/">a medida que nos especializamos nesse domínio, o modelo do negócio em nossa mente passa a ser diferente da visão inicial</a>.</p>
<p>Um exemplo simples dessa mudança acontece quando em OO criamos um relacionamento bidirecional  entre duas classes através de listas, como no exemplo a seguir:</p>
<pre class="brush: java; title: ; notranslate">
// a representação de um cliente, funcionário etc
public class Pessoa {
  List&lt;Conta&gt; contas;
}

// a representação de uma conta bancária (poupança, corrente, investimento etc)
public class Conta {
  List&lt;Pessoa&gt; pessoas;
}
</pre>
<p>A primeira vista esse é o relacionamento entre as duas entidades mas em determinado momento notamos que na verdade a relação entre pessoa e conta é um Titular, que possue características próprias, como o contrato que ele como titular da conta assinou:</p>
<pre class="brush: java; title: ; notranslate">
public class Pessoa {
  List&lt;Titular&gt; titularidades;
}
public class Conta {
  List&lt;Titular&gt; titulares;
}
public class Titular {
  Conta conta;
  Pessoa pessoa;
  // outras características de uma titularidade
}
</pre>
<p>Nesse caso o processo de refatoração envolve extrair uma classe que representa tal relação, um Titular: um exemplo simples que demonstra como em OO é comum a existência de classes para representar informações intangíveis.</p>
<p>Outras questões simples mas fundamentais para <a href="http://www.tectura.com.br/topics/nomes_complexos_descritivos_no_modelo">o bom design e legibilidade da aplicação estão ligados aos nomes que escolhemos</a>, não só em relação ao nome da classe e de seus métodos. No exemplo acima, por uma escolha fraca no nome da variável membro <b>conta</b> e <b>pessoa</b> acabamos com um código que parece repetitivo e pouco descritivo:</p>
<pre class="brush: java; title: ; notranslate">
  Pessoa pessoa;
</pre>
<p>Se em nosso sistema funcionários, gerentes, titulares e caixas são representados através de instâncias do tipo <code>Pessoa</code>, o mais adequado seria nomeá-los de acordo:</p>
<pre class="brush: java; title: ; notranslate">
public class Titular {
  Conta conta;
  Pessoa cliente;
}
</pre>
<p>A tendência natural do desenvolvedor em linguagens que obrigam a declaração do tipo é criar variáveis com nome identicos ao tipo declarado, por ser um atalho das IDEs e mais simples de escrever. Mas tais alternativas, como visto, dizem pouco sobre a variável que está sendo acessada. Por esses motivos, é muito comum encontrar código como:</p>
<pre class="brush: java; title: ; notranslate">
Cliente cliente = clienteDao.busca(13);
Pagamento pagamento = pagamentoDao.busca(15);
ProcessadorDePagamento processador =
                                new ProcessadorDePagamento();
processador.processa(cliente, pagamento);
</pre>
<p>Cliente, pagamento, processador: é somente desses três elementos que nosso domínio é composto? E nem mesmo Ruby foge disso, sendo comum encontrar:</p>
<pre class="brush: ruby; title: ; notranslate">
cliente = Cliente.find_by_id 13
pagamento = Pagamento.find_by_id 15
processador = Processador.new
processador.processa cliente, pagamento
</pre>
<p>Três aparições de cliente, três de pagamento, quatro de processador. Aqui existe uma visão distorcida de que variáveis são somente aquilo que o tipo descreve: um cliente, um pagamento, um processador. Na verdade elas referenciam instâncias específicas e especializadas de um tipo determinado. Só faria sentido chamar o cliente 13 de <b>cliente</b> se ele é o único cliente, um singleton. Especialize o nome de suas variáveis e crie um código mais legível:</p>
<pre class="brush: java; title: ; notranslate">
Cliente devedor = clientes.busca(13);
Pagamento fatura = pagamentos.busca(15);
ProcessadorDePagamento mensalidade =
                            new ProcessadorDePagamento();
mensalidade.cobra(devedor, fatura);
</pre>
<p>O mesmo pode ser refletido no exemplo de Ruby. E como trabalharemos nossos repositórios para permitir uma maior legibilidade do código?</p>
<pre class="brush: java; title: ; notranslate">
Pessoa pessoa = ...;
List&lt;Conta&gt; contas = dao.contasDe(pessoa);
</pre>
<p>Note como por causa da escolha do nome da variável <code>pessoa</code> fomos obrigados a colocar algo mais descritivo no método. Caso a variável possua um nome mais adequado, teríamos então:</p>
<pre class="brush: java; title: ; notranslate">
Pessoa cliente = ...;
List&lt;Conta&gt; contas = dao.contasDe(cliente);
</pre>
<p>Modificando nossa classe <code>Conta</code> para adicionar o gerente e o subgerente temos novamente o sentido das variáveis descrito não só pelo seu tipo, mas também pelo seu nome:</p>
<pre class="brush: java; title: ; notranslate">
public class Conta {
  List&lt;Titular&gt; titulares;
  Pessoa gerente;
  Pessoa subgerente;
}
</pre>
<p>Nesse instante a query ficaria mais complexa pois existem dois relacionamentos distintos com pessoa, requerendo <a href="http://martinfowler.com/dslwip/InternalOverview.html">a criação de uma DSL interna para query</a>. No exemplo a seguir usamos um builder para facilitar a construção da query:</p>
<pre class="brush: java; title: ; notranslate">
Pessoa gerente = ...;
Pessoa subgerente = ...;
List&lt;Conta&gt; contas =
               dao.comGerenteESubgerente
                            (gerente, subgerente):
</pre>
<p>Essa é a abordagem que o jbehave 3.2 e o selenium utilizam, onde acabamos por ter uma sintaxe muito longa e repetitiva.</p>
<p>Retomando o problema do nome das variáveis, que pode ser resolvido com outra refatoração de rename: o código da terceira linha é mais descritivo que o anterior:</p>
<pre class="brush: java; title: ; notranslate">
Pessoa gerente = ...;
Pessoa subgerente = ...;
List&lt;Conta&gt; contas =
               dao.comGerente(gerente)
                    .comSubgerente(subgerente):
</pre>
<p>Em linguagens onde mapas podem ser representados através de literais, o ruído sintático é baixo e permite que seja escrito código como a seguir em Ruby:</p>
<pre class="brush: ruby; title: ; notranslate">
gerente = ...
subgerente = ...
contas = Conta.com
              :gerente =&gt; gerente, :subgerente =&gt; subgerente
</pre>
<p>Novamente, a refatoração aqui é fundamental:</p>
<pre class="brush: ruby; title: ; notranslate">
principal = ...
secundario = ...
contas = Conta.com
              :gerente =&gt; principal, :subgerente =&gt; secundario
</pre>
<p>A escolha dos nomes de nossas classes influencia o design e legibilidade de nosso código direta e indiretamente, primeiro pela declaração das variáveis e a nossa visão do domínio. Depois pelas consequências que o mesmo possui na escolha dos nomes das variáveis e métodos, que permitem um design mais ou menos legível.</p>
<p>Essa escolha é tão importante quanto o resto de seu design para facilitar a compreensão do que seu domínio é e qual o problema que está tentando atacar. Na próxima vez que for declarar uma variável com o mesmo nome que o tipo, pense duas vezes.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/em-busca-do-nome-adequado-metodos-variaveis-e-classes/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Possibilidades de design no uso do seu Generic DAO</title>
		<link>http://blog.caelum.com.br/possibilidades-de-design-no-uso-do-seu-generic-dao/</link>
		<comments>http://blog.caelum.com.br/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[Java]]></category>
		<category><![CDATA[dao]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[di]]></category>
		<category><![CDATA[fj-25]]></category>
		<category><![CDATA[generics]]></category>
		<category><![CDATA[herança]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[oo]]></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 <a href="http://blog.caelum.com.br/possibilidades-de-design-no-uso-do-seu-generic-dao/#more-2948'" class="more-link">more &#187;</a>]]></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/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; title: ; notranslate">
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/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; title: ; notranslate">
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; title: ; notranslate">
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; title: ; notranslate">
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>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/possibilidades-de-design-no-uso-do-seu-generic-dao/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Então você quer ser um arquiteto Java?</title>
		<link>http://blog.caelum.com.br/entao-voce-quer-ser-um-arquiteto-java/</link>
		<comments>http://blog.caelum.com.br/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[Java]]></category>
		<category><![CDATA[design]]></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 <a href="http://blog.caelum.com.br/entao-voce-quer-ser-um-arquiteto-java/#more-2808'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/07/design.jpg" width="240" />
		</p><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://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/07/neo-architect.jpg"><img src="http://caelum.wpengine.netdna-cdn.com/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://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/07/design.jpg"><img src="http://caelum.wpengine.netdna-cdn.com/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>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/entao-voce-quer-ser-um-arquiteto-java/feed/</wfw:commentRss>
		<slash:comments>35</slash:comments>
		</item>
	</channel>
</rss>

