<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7837967930470422637</id><updated>2012-02-08T04:29:50.402-08:00</updated><category term='GoF Strategy'/><category term='Boas Práticas OO'/><category term='GoF Decorator'/><category term='GoF Adapter'/><category term='e-T.I.queta'/><category term='Pegadinha Java'/><title type='text'>Java, Design Patterns, OO e afins</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://marconems.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7837967930470422637/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://marconems.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Marcone</name><uri>http://www.blogger.com/profile/13438429290931637472</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_2dT5MiuZ4Y0/S_59ih5VjtI/AAAAAAAAAAM/1u7SGTtzn1g/S220/java.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>8</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7837967930470422637.post-3446891658921373798</id><published>2010-09-23T13:53:00.000-07:00</published><updated>2010-09-24T18:43:52.880-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Pegadinha Java'/><title type='text'>Pegadinha Java IV</title><content type='html'>&lt;span style="font-size:100%;"&gt;&lt;span style="font-family: arial;"&gt;Os posts marcados como "Pegadinha Java" têm a intenção de testar a sagacidade dos meus alunos iniciantes na Programação em Java. São tópicos curiosos e divertidos, e não têm a intenção de medir o conhecimento na linguagem Java.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;A vocês, meus alunos, lembrem-se que a idéia é bater o olho no código e apontar a resposta correta. Naturalmente, trata-se de pegadinhas, ou seja, são trechos de código bastante mal-intencionados... :-)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;Nesta nova questão, uma perguntinha básica: em Java é possível dar new em Interface?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;Antes de me responder, analise o código abaixo: temos uma interface chamada "Exemplo" e no mesmo arquivo, uma inner class chamada "Classe". Logo na primeira linha da classe, encontramos um bendito "new Exemplo()", ou seja, new em Interface.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;Em meio ao código, alguns comentários. A parte chata da estória: este código compila sem erros!!!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;Mas como? Isto não é proibido?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;Copie todo o código junto, cole em um mesmo arquivo com o nome da interface pública (Exemplo.java), compile e ateste: sem erros! Por quê????&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;Abraço a todos e até o próximo post! :P&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=";font-family:courier;font-size:60;"  &gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=";font-family:courier;font-size:60;"  &gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;/*/ Isto é apenas comentário: abaixo está a interface /*/&lt;br /&gt;&lt;br /&gt;public interface Exemplo {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;void mostra();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*/ A classe abaixo vai dar new em interface! /*/&lt;br /&gt;class Classe{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Exemplo exemplo = new Exemplo() /*/ (Aqui está!) // ;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/*/ /*/ [Sabia que isto era possível???] /*/&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/*/} Eu não sabia! /*/{&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public void mostra() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;System.out.println("Interessante!");&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/*/ &gt;&gt; Pior que isto compila sem erros!! &lt;&lt; //&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//*; { Por quê? /*/};&lt;br /&gt;&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt; &lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier;font-size:60;"  &gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7837967930470422637-3446891658921373798?l=marconems.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://marconems.blogspot.com/feeds/3446891658921373798/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://marconems.blogspot.com/2010/09/pegadinha-java-iv.html#comment-form' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7837967930470422637/posts/default/3446891658921373798'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7837967930470422637/posts/default/3446891658921373798'/><link rel='alternate' type='text/html' href='http://marconems.blogspot.com/2010/09/pegadinha-java-iv.html' title='Pegadinha Java IV'/><author><name>Marcone</name><uri>http://www.blogger.com/profile/13438429290931637472</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_2dT5MiuZ4Y0/S_59ih5VjtI/AAAAAAAAAAM/1u7SGTtzn1g/S220/java.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7837967930470422637.post-8889617401658682195</id><published>2010-06-01T14:36:00.000-07:00</published><updated>2010-06-01T14:47:02.193-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='e-T.I.queta'/><title type='text'>e-T.I.queta</title><content type='html'>&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-weight: bold;"&gt;Regras de etiqueta para o profissional de T.I.&lt;/span&gt; (Tecnologia da Informação)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Você já teve um professor de T.I. que parecia explicar o assunto para quem já soubesse do assunto?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Já foi a alguma palestra de T.I. em que o palestrante passou a imagem de ser um expert - mas você não entendeu nada do que ele disse?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Infelizmente, isto acontece com muita frequência, especialmente em nossa área de tecnologia.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Talvez o professor e o palestrante acima precisassem saber de algumas regras, como as listadas a seguir.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Se você é um profissional de T.I. e vai apresentar uma aula, ou uma palestra, precisa entender que:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;1) Você vai ser bem sucedido em sua apresentação apenas se os espectadores entenderem com clareza o que você apresentou! Se eles ficarem com a impressão de que você deve conhecer muito bem o assunto, mas não entenderem nada do que você apresentou, acredite: você falhou em seu propósito!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;2) Falar muitas siglas deve impressionar algumas pessoas, e na área de T.I. é quase impossível não utilizá-las: JEE, EJB, SOA... Mas se você vai, por exemplo, apresentar uma palestra sobre SOA, considere a possibilidade das pessoas não saberem o quê significa SOA. Faça uma breve introdução e esclareça o significado das principais siglas que você vai utilizar. A propósito: SOA significa "Service-oriented architecture" (Arquitetura Orientada a Serviços).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;3) Se você se propôs a proferir uma palestra, assuma a missão de esclarecer, e não complicar, o assunto. O palco da apresentação não é o lugar mais apropriado para você demonstrar suas habilidades em falar difícil. Se o seu propósito é apenas exibir seus conhecimentos, inscreva-se numa maratona.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;4) Não confunda "Marketing Pessoal" com "Exibicionismo Vazio". Você fará um excelente marketing de si mesmo ao demonstrar que possui boa didática e que consegue esclarecer um assunto complicado. Quem vai assistir a sua palestra, ou a sua aula, tem a intenção (mínima que seja) de aprender sobre o tema.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;5) Ao preparar o material da sua apresentação (como slides, etc) procure manter o máximo de simplicidade. Seja objetivo, e elimine tudo o que não for estritamente necessário. Por exemplo: se você já disse que "o sistema funciona como se fossem 3 módulos se comunicando" então o gráfico abaixo é inteiramente inútil:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_2dT5MiuZ4Y0/TAV9ueu1C9I/AAAAAAAAAAw/m2tsTQUhAvs/s1600/imagem.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 311px; height: 320px;" src="http://2.bp.blogspot.com/_2dT5MiuZ4Y0/TAV9ueu1C9I/AAAAAAAAAAw/m2tsTQUhAvs/s320/imagem.jpg" alt="" id="BLOGGER_PHOTO_ID_5477922759243008978" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:arial;"&gt;Ele se torna mais inútil ainda se estiver desenhado em 3 dimensões, com 32 cores. Não precisa passar a impressão de que você é um grande conhecedor de ferramentas gráficas.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;6) Se você tem receio de que, ao apresentar sua palestra, alguém possa roubar a sua idéia genial sobre o tema, então não se ofereça a dar uma palestra sobre o tema. Seja um palestrante somente se você estiver disposto a explicar com clareza o assunto em questão.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;7) Depois da sua apresentação, procure obter opiniões dos espectadores. Seu endereço de e-mail para contato, escrito no último slide da apresentação, é uma ótima idéia. Diga que você aceita sugestões para a melhoria constante da sua aula ou palestra.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;8) Leia os e-mails com as sugestões enviadas pelos espectadores. Procure assimilar, com senso crítico, aquilo que costuma aparecer repetidamente como sugestão.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Acredito que desta forma, com estas regras simples, possamos tornar a área de T.I. melhor a cada dia, com melhores profissionais, dispostos a compartilhar o conhecimento entre si. Fique à vontade para enviar o link deste post ao seu professor que complica mais do que explica. Fique à vontade para me enviar mais regras de etiqueta que você gostaria de acrescentar aqui. E, por fim, fique à vontade para me enviar críticas ou sugestões sobre qualquer assunto deste blog.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Um abraço e até o próximo post!&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7837967930470422637-8889617401658682195?l=marconems.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://marconems.blogspot.com/feeds/8889617401658682195/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://marconems.blogspot.com/2010/06/e-tiqueta-i.html#comment-form' title='4 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7837967930470422637/posts/default/8889617401658682195'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7837967930470422637/posts/default/8889617401658682195'/><link rel='alternate' type='text/html' href='http://marconems.blogspot.com/2010/06/e-tiqueta-i.html' title='e-T.I.queta'/><author><name>Marcone</name><uri>http://www.blogger.com/profile/13438429290931637472</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_2dT5MiuZ4Y0/S_59ih5VjtI/AAAAAAAAAAM/1u7SGTtzn1g/S220/java.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_2dT5MiuZ4Y0/TAV9ueu1C9I/AAAAAAAAAAw/m2tsTQUhAvs/s72-c/imagem.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7837967930470422637.post-1866180075247996459</id><published>2010-06-01T04:10:00.000-07:00</published><updated>2010-06-02T03:48:38.475-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Boas Práticas OO'/><category scheme='http://www.blogger.com/atom/ns#' term='GoF Strategy'/><title type='text'>IF bom é IF morto!</title><content type='html'>&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:arial;"&gt;O título deste post se refere a uma boa prática em programação Orientada a Objetos. Nossa equipe de desenvolvimento já adotou este lema, e sempre que chega um colega novato, fazemos questão de apresentá-lo a esta lei: "É proibido utilizar IFs negociais", ou, melhor ainda: "&lt;span style="font-weight: bold;"&gt;IF BOM É IF MORTO&lt;/span&gt;".&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Ao ouvir esta lei, a primeira pergunta óbvia que escutamos é: - "Se não posso utilizar IF, então vou utilizar o quê? Switch-Case?"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;A resposta é: &lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Não!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Na verdade, não devemos utilizar nem IFs,  nem Switch-Case, nem qualquer outra estrutura condicional em nosso código!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Aqui, vamos chamar toda e qualquer estrutura de decisão - seja IF, Switch-Case, ou qualquer outra - apenas como IF pra facilitar.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;E por quê não podemos utilizar IF em nosso  código?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Pelo seguinte motivo: queremos nos beneficiar das inúmeras vantagens da Orientação a Objetos, e o IF nos remete à velha e ultrapassada programação estruturada. Aliás, o IF é a própria estruturação do código que desejamos evitar:&lt;/span&gt;&lt;pre&gt;&lt;span style="font-family:arial;"&gt;SE isso &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;       FAÇA aquilo&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;SENÃO&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;       FAÇA aquilo outro&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;SWITCH(numero)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;       CASO 1: faça aquilo&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;       CASO 2: faça aquilo outro&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;       etc etc&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt; &lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:arial;"&gt;Ou seja, é a própria essência da estruturação, ou pelo menos, a característica mais &lt;span style="font-weight: bold;"&gt;engessada&lt;/span&gt; da programação estruturada! Ela demanda várias manutenções no código, sempre que um novo Caso for identificado. Ora, mas dentre outras coisas, não queremos utilizar a OO para minimizar o impacto das alterações?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Então, tome nota desta Lei: &lt;span style="font-weight: bold;"&gt;IF BOM É IF  MORTO&lt;/span&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;O questionamento que escutamos em seguida pelos programadores novatos é: - "Mas se não posso usar nem IF, nem Switch-Case, nem nada parecido, COMO é que vou tratar isso?"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;É o que veremos a seguir. A regra do nosso exemplo diz que: o programa deverá receber do usuário uma informação "PF" ou "PJ", indicando se vai tratar de Pessoa Física ou Pessoa Jurídica.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;SE for pessoa física, o sistema imprime na tela "Pessoa Física", consulta e grava dados num banco Oracle, envia um e-mail automático para a Empresa X, gera um LOG numa pasta específica, e imprime um Relatório de PF.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;SE for pessoa jurídica, o sistema imprime na tela "Pessoa Jurídica", consulta e grava dados num banco DB2, envia 3 e-mails automáticos para a Empresa X, Y, Z, gera um LOG em outra pasta específica, e imprime 2 Relatórios de PJ.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Implementando da maneira estruturada, teríamos o seguinte:&lt;/span&gt;&lt;pre&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:courier new;"&gt;public class  Executavel{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  public static void main(String[] args){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;      String tipo = args[0];&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;      if(tipo.equals("PF")){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;          System.out.println("Pessoa Física");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;          System.out.println("Consultando Oracle...");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;      }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;      if(tipo.equals("PJ")){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;          System.out.println("Pessoa Jurídica");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;          System.out.println("Consultando DB2...");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;      }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;      GeraMail.trataTipo(tipo);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;      TrataLog.grava(tipo);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;      Relatorio.imprime(tipo);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;span style="font-family:arial;"&gt;Um exemplo simples, que recebe o parâmetro do usuário na linha de comando, sem muito tratamento, apenas para ilustrar os malefícios da abordagem estruturada com IFs.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;O "arquiteto" que projetou a solução acima, baseou toda a solução nos IFs. Note que, na chamada a GeraMail.trata(tipo), ele precisa enviar a informação do usuário (PF ou PJ), e dentro desta classe vamos ter outra estrutura de IFs para tratar o envio de e-mail. O mesmo acontece com TrataLog e Relatorio, replicando a estrutura de IFs por diversas partes do código.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Ao projetar a "brilhante" solução acima, o "arquiteto genial" pensou: - "Bem, os 2 únicos tipos possíveis neste caso para pessoa é Física ou Jurídica. Então, vou fazer com IFs mesmo". Aí então, 4 meses de trabalho depois, com toda a "arquitetura" pronta e faltando 1 semana para o prazo final da entrega do projeto, ele recebe um telefonema do Cliente, que diz: - "Preciso tratar mais um tipo! Se refere à PJS - Pessoa Jurídica optante pelo Simples, que, no meu requisito, vai possuir regras completamente diferentes dos outros tipos".&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Pânico! Desespero! Ele precisa alterar o método main() acima para inserir mais um tratamento, e precisa alterar a classe GeraMail para tratar mais um IF, e precisa dar manutenção também na classe TrataLog, e também na Relatorio, e em mais 7.586 classes do sistema...  :-)   [...geralmente é o que acontece na prática, além de ter que testar tudo novamente...] Ou seja, muitas noites sem dormir, trabalho no sábado e domingo, aumento enorme da probabilidade de falhas no sistema, e muito provavelmente, mais um projeto que vai estourar custo e prazo!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Tudo porque ele negligenciou o nosso lema: &lt;span style="font-weight: bold;"&gt;IF BOM É IF MORTO&lt;/span&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Como fazer sem usar IFs? Assim:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Vou criar a interface &lt;span style="font-weight: bold;"&gt;Pessoa&lt;/span&gt;:&lt;/span&gt;&lt;pre&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:courier new;"&gt; public interface Pessoa{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        public void imprime();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;span style="font-family:arial;"&gt;Vou criar a classe PessoaFisica, que vai conter todos os tratamentos que são de responsabilidade de PF (gravar no Oracle, enviar e-mail para X, etc), e a classe PessoaJuridica, que vai tratar regras de PJ (grava no DB2, etc, etc). Ambas as classes vão implementar a interface Pessoa.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Apenas para que possamos rodar o nosso exemplo, e ver a solução funcionando na prática, vou fazer com que as classes PF e PJ exibam na tela suas informações, sem tratar acesso a banco nem como gerar logs, etc (não é assunto deste post).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;A classe &lt;span style="font-weight: bold;"&gt;PessoaFisica.java&lt;/span&gt; ficaria assim:&lt;/span&gt;&lt;pre&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:courier new;"&gt;public class PessoaFisica implements Pessoa{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   public void imprime(){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;      System.out.println("Pessoa Física");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;      System.out.println("Consultando Oracle...");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;span style="font-family:arial;"&gt;A classe &lt;span style="font-weight: bold;"&gt;PessoaJuridica.java&lt;/span&gt; ficaria assim:&lt;/span&gt;&lt;pre&gt;&lt;span style=";font-family:courier new;font-size:100%;"  &gt;public class PessoaJuridica implements Pessoa{&lt;br /&gt;   public void imprime(){&lt;br /&gt;      System.out.println("Pessoa Jurídica");&lt;br /&gt;      System.out.println("Consultando DB2...");&lt;br /&gt;   }&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;span style="font-family:arial;"&gt;Agora, sem os malditos IFs, a mesma classe &lt;span style="font-weight: bold;"&gt;Executavel.java&lt;/span&gt; do início do exemplo:&lt;/span&gt;&lt;pre&gt;&lt;span style=";font-family:courier new;font-size:100%;"  &gt;public class Executavel{&lt;br /&gt;  public static void main(String[] args){&lt;br /&gt;     Map mapaDePessoas = new HashMap();&lt;br /&gt;     mapaDePessoas.put("PF", new PessoaFisica());&lt;br /&gt;     mapaDePessoas.put("PJ", new PessoaJuridica());&lt;br /&gt;     String tipo = args[0];&lt;br /&gt;     Pessoa pessoa = (Pessoa) mapaDePessoas.get(tipo);&lt;br /&gt;     pessoa.imprime();&lt;br /&gt;  }&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;span style="font-family:arial;"&gt;Compile, rode e ateste a eficácia da solução:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;/&gt; java Executavel PF&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Pessoa Física&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Consultando Oracle...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;/&gt; java Executavel PJ&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Pessoa Jurídica&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Consultando DB2...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Pronto! De acordo com a informação dada pelo usuário, executei regras diferentes sem utilizar 1 único IF (nem Switch-Case...)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;E se eu precisar de um novo tipo para Pessoa Jurídica optante pelo Simples - PJS? Aí então eu vou criar esta nova classe PJS, com suas regras específicas, e adicionar uma entrada no Mapa:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:arial;" &gt;mapaDePessoas.put("PJS", new PJS());&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;E só! Nenhum outro ponto em todo o Projeto precisaria ser alterado!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Por fim, vale ressaltar que a desvantagem do IF é esta propagação de manutenções que ele demanda em caso de alteração. Entretanto, para utilizar o mecanismo da &lt;a href="http://en.wikipedia.org/wiki/Lazy_loading"&gt;inicialização tardia&lt;/a&gt;, podemos fazer o trecho abaixo sem problemas:&lt;/span&gt;&lt;pre&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:courier new;"&gt;public Conexao  getConexao(){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   if(this.conexao == null){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        this.conexao = new Conexao();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   return this.conexao;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;span style="font-family:arial;"&gt;Você pode estar pensando: - "Mas você disse que é proibido utilizar IFs". Não, eu não disse isso!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;O que eu disse foi: é proibido usar IFs negociais! Este não é um IF negocial, ele apenas testa o valor nulo. Ou, como diz a nossa Lei: "IF BOM É IF MORTO". Exatamente! Este IF acima está morto! Ou seja, não há a menor possibilidade de ele vir sofrer alterações futuramente. Na inicialização tardia, eu testo se o valor é nulo, e isto nunca vai ser alterado. O Cliente pode mudar todos os seus requisitos que, ainda assim, o método getConexao() acima vai continuar como está!&lt;br /&gt;&lt;br /&gt;O exemplo aqui apresentado é uma implementação do GoF Pattern &lt;span style="font-weight: bold;"&gt;Strategy&lt;/span&gt;. As classes PessoaFisica e PessoaJuridica podem ser entendidas como estratégias que encapsulam seus algoritmos. Pretendo abordar o Strategy em outro post, específico sobre este padrão, para que possamos ver outros exemplos e discutir as abordagens do GoF. Até lá!&lt;br /&gt;&lt;br /&gt;(*PS: não deixe de enviar seu comentário, dúvida, crítica, sugestões, discordâncias, perguntas, reclamações...)&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7837967930470422637-1866180075247996459?l=marconems.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://marconems.blogspot.com/feeds/1866180075247996459/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://marconems.blogspot.com/2010/06/if-bom-e-if-morto.html#comment-form' title='14 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7837967930470422637/posts/default/1866180075247996459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7837967930470422637/posts/default/1866180075247996459'/><link rel='alternate' type='text/html' href='http://marconems.blogspot.com/2010/06/if-bom-e-if-morto.html' title='IF bom é IF morto!'/><author><name>Marcone</name><uri>http://www.blogger.com/profile/13438429290931637472</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_2dT5MiuZ4Y0/S_59ih5VjtI/AAAAAAAAAAM/1u7SGTtzn1g/S220/java.jpg'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7837967930470422637.post-24772346925233370</id><published>2010-05-28T10:55:00.001-07:00</published><updated>2010-06-01T14:32:47.283-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Pegadinha Java'/><title type='text'>Pegadinha Java III</title><content type='html'>&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:arial;"&gt;Os posts marcados como "Pegadinha Java" têm a intenção de testar a sagacidade dos meus alunos &lt;span style="font-weight: bold;"&gt;iniciantes&lt;/span&gt; na Programação em Java. São tópicos curiosos e divertidos, e &lt;span style="font-weight: bold;"&gt;não têm&lt;/span&gt; a intenção de medir o conhecimento na linguagem Java.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;A vocês, meus alunos, lembrem-se que a idéia é bater o olho no código e apontar a resposta correta. Naturalmente, trata-se de pegadinhas, ou seja, são trechos de código bastante mal-intencionados... :-)&lt;br /&gt;&lt;br /&gt;Nesta terceira questão, considere o seguinte trecho de código:&lt;pre&gt;&lt;span style="font-family:courier new;"&gt;public class Executavel{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;     public static void main(String[] args){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            http://java.sun.com&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            System.exit(0);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;      }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;Você deve estar pensando (ou pelo menos deveria): - Ei, esta terceira linha de código não é uma instrução válida do Java!&lt;br /&gt;&lt;br /&gt;Exatamente! No entanto, eu digo a você que este trecho compila e roda sem erros!&lt;br /&gt;&lt;br /&gt;E, infelizmente, você não pode afirmar o contrário, pois o contrário nem existe entre as respostas válidas... :-)&lt;br /&gt;&lt;br /&gt;Portanto, marque abaixo a &lt;span style="font-weight: bold;"&gt;única&lt;/span&gt; alternativa correta:&lt;br /&gt;&lt;br /&gt;a - compila e roda sem erros, mas não acontece nada.&lt;br /&gt;b - compila e roda sem erros, e abre o browser com a página da Sun.&lt;br /&gt;c - não é possível que isto compile!! A 3ª linha nem é código-java.&lt;br /&gt;d - se isto compilar e rodar sem erros, minha JVM ficou maluca!&lt;br /&gt;e - tem certeza que isto compila???&lt;br /&gt;&lt;br /&gt;E a alternativa correta é a letra.......................... &lt;span style="font-weight: bold;font-size:180%;" &gt;A&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Muito bem! A resposta correta, como vocês podem conferir na máquina de vocês, é: "Compila e roda sem erros, mas não acontece nada". Mas o quê eu queria saber mesmo é:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Por quê isto compila e roda sem erros, se a 3ª linha não é código java?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Abraços a todos e até o próximo post!&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7837967930470422637-24772346925233370?l=marconems.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://marconems.blogspot.com/feeds/24772346925233370/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://marconems.blogspot.com/2010/05/pegadinha-java-3.html#comment-form' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7837967930470422637/posts/default/24772346925233370'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7837967930470422637/posts/default/24772346925233370'/><link rel='alternate' type='text/html' href='http://marconems.blogspot.com/2010/05/pegadinha-java-3.html' title='Pegadinha Java III'/><author><name>Marcone</name><uri>http://www.blogger.com/profile/13438429290931637472</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_2dT5MiuZ4Y0/S_59ih5VjtI/AAAAAAAAAAM/1u7SGTtzn1g/S220/java.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7837967930470422637.post-3113637183208174942</id><published>2010-05-28T09:38:00.001-07:00</published><updated>2010-06-01T14:33:24.201-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Pegadinha Java'/><title type='text'>Pegadinha Java II</title><content type='html'>&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:arial;"&gt;Os posts marcados como "Pegadinha Java" têm a intenção de testar a sagacidade dos meus alunos &lt;span style="font-weight: bold;"&gt;iniciantes&lt;/span&gt; na Programação em Java. São tópicos curiosos e divertidos, e &lt;span style="font-weight: bold;"&gt;não têm&lt;/span&gt; a intenção de medir o conhecimento na linguagem Java.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;A vocês, meus alunos, lembrem-se que a idéia é bater o olho no código e apontar a resposta correta. Naturalmente, trata-se de pegadinhas, ou seja, são trechos de código bastante mal-intencionados... :-)&lt;br /&gt;&lt;br /&gt;Nesta segunda questão, vocês devem se lembrar do trecho de código abaixo:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;System.out.println("010" + 10)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Todos vão se lembrar que o resultado &lt;span style="font-weight: bold;"&gt;não vai ser 20 &lt;/span&gt;e sim 01010. A explicação é fácil, pois o primeiro fator da soma é um String, logo ele vai converter o segundo fator também para String e concatenar os dois fatores.&lt;br /&gt;&lt;br /&gt;Mas e o techo abaixo:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;System.out.println(010 + 010)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;O primeiro fator é numérico, logo o resultado da soma vai ser...&lt;br /&gt;&lt;br /&gt;Muito bem!  &lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;16&lt;/span&gt;&lt;/span&gt;      &lt;span style="font-size:180%;"&gt;(!!!)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Por quê?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:arial;"&gt;Àqueles que descobriram a resposta, tenham a gentileza de não estragar a surpresa... :-)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Só me enviem mensagens se tiverem dúvidas, mas não revelem a resposta para os demais, certo?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Um abraço e até a próxima!&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7837967930470422637-3113637183208174942?l=marconems.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://marconems.blogspot.com/feeds/3113637183208174942/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://marconems.blogspot.com/2010/05/pegadinha-java-2.html#comment-form' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7837967930470422637/posts/default/3113637183208174942'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7837967930470422637/posts/default/3113637183208174942'/><link rel='alternate' type='text/html' href='http://marconems.blogspot.com/2010/05/pegadinha-java-2.html' title='Pegadinha Java II'/><author><name>Marcone</name><uri>http://www.blogger.com/profile/13438429290931637472</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_2dT5MiuZ4Y0/S_59ih5VjtI/AAAAAAAAAAM/1u7SGTtzn1g/S220/java.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7837967930470422637.post-7725045066807221797</id><published>2010-05-28T08:19:00.001-07:00</published><updated>2010-06-01T14:33:47.651-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Pegadinha Java'/><title type='text'>Pegadinha Java I</title><content type='html'>&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:arial;"&gt;Os posts marcados como "Pegadinha Java" têm a intenção de testar a sagacidade dos meus alunos &lt;span style="font-weight: bold;"&gt;iniciantes&lt;/span&gt; na Programação em Java. São tópicos curiosos e divertidos, e &lt;span style="font-weight: bold;"&gt;não têm&lt;/span&gt; a intenção de medir o conhecimento na linguagem Java.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;A vocês, meus alunos, lembrem-se que a idéia é bater o olho no código e apontar a resposta correta. Naturalmente, trata-se de pegadinhas, ou seja, são trechos de código bastante mal-intencionados... :-)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Nesta primeira questão, pergunto: vocês sabem somar 21 + 5?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Bem simples, certo? Então me digam o que será mostrado no trecho de código abaixo:&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;pre&gt;&lt;span style="font-family:courier new;"&gt;public class Executavel{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public static void main(String [] args){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;         System.out.println(2l + 5);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;Muito bem! O resultado &lt;span style="font-weight: bold;"&gt;não é 26&lt;/span&gt;. Mas, por quê não é 26?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Bom, esta é a resposta que eu espero de vocês, esforçados alunos! Copiem o código acima, colem no editor Java, compilem, rodem, e me digam por quê o resultado mostrado não foi 26. (*Lembrem-se, vocês têm que copiar e colar o código acima, não vale digitar vocês mesmos).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Àqueles que descobriram a resposta, tenham a gentileza de não estragar a surpresa... :-)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Só me enviem mensagens se tiverem dúvidas, mas não revelem a resposta para os demais, certo?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Um abraço e até a próxima!&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7837967930470422637-7725045066807221797?l=marconems.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://marconems.blogspot.com/feeds/7725045066807221797/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://marconems.blogspot.com/2010/05/pegadinha-java-1.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7837967930470422637/posts/default/7725045066807221797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7837967930470422637/posts/default/7725045066807221797'/><link rel='alternate' type='text/html' href='http://marconems.blogspot.com/2010/05/pegadinha-java-1.html' title='Pegadinha Java I'/><author><name>Marcone</name><uri>http://www.blogger.com/profile/13438429290931637472</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_2dT5MiuZ4Y0/S_59ih5VjtI/AAAAAAAAAAM/1u7SGTtzn1g/S220/java.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7837967930470422637.post-1032991382063491062</id><published>2010-05-28T04:34:00.000-07:00</published><updated>2010-05-28T11:41:01.952-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GoF Adapter'/><title type='text'>Adapter</title><content type='html'>&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:arial;"&gt;De acordo com GoF, Adapter serve para "converter a interface de uma classe em outra interface esperada pelos clientes. O Adapter permite que certas classes trabalhe em conjunto, pois de outra forma seria impossível por causa de suas interfaces incompatíveis".&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Para exemplificar, vou exibir uma situação simples em que se pode implementar o Adapter. A idéia deste blog é fazer com que você possa entender como funcionam os Padrões, e a partir daí, possa utilizá-lo em sua situação prática.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;No nosso exemplo, vamos imaginar que você tenha uma classe responsável por imprimir seus relatórios. O nome desta classe é &lt;span style="font-weight: bold;"&gt;PrintaRelatorio&lt;/span&gt;, e ela vai possuir um atributo chamado &lt;span style="font-weight: bold;"&gt;out&lt;/span&gt; do tipo &lt;span style="font-weight: bold;"&gt;PrintStream&lt;/span&gt;. É um objeto que todos os desenvolvedores Java conhecem bem, utilizado sempre que mostramos algo na tela com &lt;span style="font-weight: bold;"&gt;System.out.println("texto")&lt;/span&gt;; é o mesmo &lt;span style="font-weight: bold;"&gt;System.out&lt;/span&gt; que nossa classe vai utilizar. Ela terá um método chamado imprime que receberá uma &lt;span style="font-weight: bold;"&gt;String&lt;/span&gt; como parâmetro e imprimirá na tela o resultado.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;O código completo de &lt;span style="font-weight: bold;"&gt;PrintaRelatorio.java&lt;/span&gt; será:&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;pre&gt;&lt;span style="font-family:courier new;"&gt;public class PrintaRelatorio {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   private PrintStream out;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   public PrintStream getOut(){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;      return this.out;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   public void setOut(PrintStream out) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;      this.out = out;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   public void imprime(String texto){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;       getOut().println(texto);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;Um atributo out do tipo &lt;span style="font-weight: bold;"&gt;PrintStream&lt;/span&gt;, seus getters e setters, e o método &lt;span style="font-weight: bold;"&gt;imprime()&lt;/span&gt; recebendo como parâmetro o texto a ser mostrado no console da aplicação com &lt;span style="font-weight: bold;"&gt;println()&lt;/span&gt;. Bastante simples!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Para utilizar a funcionalidade da classe acima, bastaria fazer em nossa classe Executável:&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;pre&gt;&lt;span style="font-family:courier new;"&gt;public static void main(String[] args) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  PrintaRelatorio printa = new PrintaRelatorio();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  printa.setOut(System.out);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  printa.imprime("texto");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;O requisito do Cliente era apenas este: ter uma classe que permita imprimir no console uma informação. Está feito!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Entretanto, como todo analista sabe muito bem, um &lt;span style="font-weight: bold;"&gt;requisito serve para ser alterado pelo Cliente, várias vezes, durante todo o projeto&lt;/span&gt;!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Em nosso exemplo, o Cliente quer agora que a informação seja exibida em uma "telinha bonitinha" e não mais no console da linha de comando. Porém, a classe &lt;span style="font-weight: bold;"&gt;PrintaRelatorio&lt;/span&gt; já está homologada em produção, sendo utilizada por vários outros programas, permeada em diversos sistemas... e o fato é que você &lt;span style="font-weight: bold;"&gt;não vai poder mexer em PrintaRelatorio.java&lt;/span&gt;!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;E assim surge o nosso primeiro problema: para exibir a informação na tela que o Cliente deseja, precisaremos utilizar &lt;span style="font-weight: bold;"&gt;JOptionPane.showMessageDialog()&lt;/span&gt; no lugar de &lt;span style="font-weight: bold;"&gt;System.out.println()&lt;/span&gt;. Porém, eu &lt;span style="font-weight: bold;"&gt;não&lt;/span&gt; posso fazer  &lt;span style="font-weight: bold;"&gt;printaRelatorio.setOut(JOptionPane)&lt;/span&gt; porque este método espera algo do tipo &lt;span style="font-weight: bold;"&gt;PrintStream&lt;/span&gt;. Além do mais, o método &lt;span style="font-weight: bold;"&gt;imprime()&lt;/span&gt; de printaRelatorio invoca o &lt;span style="font-weight: bold;"&gt;println()&lt;/span&gt;, e eu preciso invocar &lt;span style="font-weight: bold;"&gt;showMessageDialog()&lt;/span&gt;. Como resolver isso &lt;span style="font-weight: bold;"&gt;sem alterar a classe PrintaRelatorio&lt;/span&gt;?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Resposta: aplicando o padrão &lt;span style="font-weight: bold;"&gt;Adapter&lt;/span&gt;. De novo, GoF: "converte a interface de uma classe em outra interface esperada pelos clientes". É a mesma situação que temos!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Vou criar uma classe chamada &lt;span style="font-weight: bold;"&gt;AdaptadoraParaPainel&lt;/span&gt; que vai estender PrintStream:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:arial;" &gt;public class AdaptadoraParaPainel extends PrintStream&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Ao fazer isso, ela me obriga a inserir um construtor para informar um Arquivo, visto que a especialidade dela é trabalhar com streams. Mas eu não vou trabalhar com arquivos! Então vou inserir o construtor que ela espera, declarar a exceção que ela espera, apenas para o compilador parar de reclamar. Ou seja:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:arial;" &gt;//Construtor&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:arial;" &gt;public AdaptadoraParaPainel() throws FileNotFoundException{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:arial;" &gt;     .....super(new File("nada"));&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:arial;" &gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Aí então vou inserir o método que a classe cliente espera que eu chame, com a mesma assinatura, mas invocando o mecanismo que eu preciso agora, que é &lt;span style="font-weight: bold;"&gt;showMessageDialog()&lt;/span&gt;. Isto é:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:arial;" &gt;public void print(String texto){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:arial;" &gt;.....JOptionPane.showMessageDialog(null,texto);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:arial;" &gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Portanto, assim fica o código completo de &lt;span style="font-weight: bold;"&gt;AdaptadoraParaPainel.java&lt;/span&gt; :&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;pre&gt;&lt;span style="font-family:courier new;"&gt;import java.io.File;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;import java.io.FileNotFoundException;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;import java.io.PrintStream;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;import javax.swing.JOptionPane;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public class AdaptadoraParaPainel&lt;br /&gt;          extends PrintStream {&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;   public AdaptadoraParaPainel()&lt;br /&gt;       throws FileNotFoundException{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;      super(new File("nada"));&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   public void print(String texto){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;      JOptionPane.showMessageDialog(null,texto);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;Com isso, minha classe cliente vai poder continuar invocando o método &lt;span style="font-weight: bold;"&gt;setOut()&lt;/span&gt; que espera um &lt;span style="font-weight: bold;"&gt;PrintStream&lt;/span&gt;: a minha classe adaptadora &lt;span style="font-weight: bold;"&gt;é um PrintStream&lt;/span&gt;! O código completo da classe &lt;span style="font-weight: bold;"&gt;Executavel.java&lt;/span&gt; seria:&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;pre&gt;&lt;span style="font-family:courier new;"&gt;import java.io.FileNotFoundException;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;import java.io.PrintStream;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public class Executavel {&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;   public static void main(String[] args) throws&lt;br /&gt;                  FileNotFoundException {&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;      PrintaRelatorio printa = new PrintaRelatorio();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;      printa.setOut(new AdaptadoraParaPainel());&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;      printa.imprime("texto");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;Pronto! A informação impressa em uma tela e não mais no console, como queria o Cliente, e a classe PrintaRelatorio permanece intocada.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Mas eu ainda tenho algo &lt;span style="font-weight: bold;"&gt;importante&lt;/span&gt; a dizer. Na situação apresentada aqui, o padrão Adapter precisou ser utilizado, de fato. Porém, é preciso notar que: um bom projetista, um arquiteto competente, &lt;span style="font-weight: bold;"&gt;não teria&lt;/span&gt; deixado isto acontecer! A forma como foi construída a classe PrintaRelatorio deixou o mecanismo amarrado ao PrintStream! &lt;span style="font-weight: bold;"&gt;Esta foi uma péssima decisão!&lt;/span&gt; Um&lt;span style="font-weight: bold;"&gt; bom arquiteto&lt;/span&gt; teria notado que:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;"Peraí! O Cliente está me pedindo um objeto para imprimir no console. Mas vai que amanhã ele mude de idéia e queira imprimir numa tela? Ou numa página html? Ou direto na impressora? Ou enviar por e-mail? Afinal de contas, &lt;span style="font-weight: bold;"&gt;um requisito do Cliente foi feito para ser alterado, diversas vezes, durante o projeto...&lt;/span&gt;"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Um &lt;span style="font-weight: bold;"&gt;bom arquiteto&lt;/span&gt; teria construído sua classe aplicando o &lt;span style="font-weight: bold;"&gt;Padrão Bridge&lt;/span&gt;. Diz o GoF sobre o Bridge: "desacopla uma abstração da sua implementação, de modo que as duas possam variar independentemente". Se o Padrão Bridge tivesse sido aplicado, não teríamos a necessidade de adaptar mais tarde.&lt;br /&gt;&lt;br /&gt;O &lt;span style="font-weight: bold;"&gt;livro do GoF&lt;/span&gt;, na &lt;span style="font-weight: bold;"&gt;página 160&lt;/span&gt;, diz que:&lt;/span&gt; &lt;span style="font-family:arial;"&gt;"O padrão &lt;span style="font-weight: bold;"&gt;Adapter&lt;/span&gt; é orientado para fazer com que classes não-relacionadas trabalhem em conjunto. Ele é normalmente aplicado a sistemas que já foram projetados. Por outro lado, &lt;span style="font-weight: bold;"&gt;Bridge&lt;/span&gt; é usado em um projeto, desde o início, para permitir que abstrações e implementações possam variar independentemente."&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Mas o Padrão Bridge é assunto para outro post. Não deixe de me enviar uma mensagem em caso de críticas, sugestões ou dúvidas. Obrigado e até a próxima.&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7837967930470422637-1032991382063491062?l=marconems.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://marconems.blogspot.com/feeds/1032991382063491062/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://marconems.blogspot.com/2010/05/adapter.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7837967930470422637/posts/default/1032991382063491062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7837967930470422637/posts/default/1032991382063491062'/><link rel='alternate' type='text/html' href='http://marconems.blogspot.com/2010/05/adapter.html' title='Adapter'/><author><name>Marcone</name><uri>http://www.blogger.com/profile/13438429290931637472</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_2dT5MiuZ4Y0/S_59ih5VjtI/AAAAAAAAAAM/1u7SGTtzn1g/S220/java.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7837967930470422637.post-4960834678481116605</id><published>2010-05-26T11:59:00.001-07:00</published><updated>2010-05-28T09:03:36.167-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GoF Decorator'/><title type='text'>Decorator</title><content type='html'>&lt;span style=";font-family:arial;font-size:100%;"  &gt;Segundo o GoF, "os Decorators fornecem uma alternativa flexível a subclasses para &lt;/span&gt;&lt;span style="font-weight: bold;font-family:arial;font-size:100%;"  &gt;extensão&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt; da funcionalidade".&lt;br /&gt;&lt;br /&gt;A palavra importante aí é "extensão". Ao se criar um objeto decorador, ele não deverá ter conhecimento da classe que ele vai decorar. Um decorador "barra de rolagem" só deverá saber que ele vai extender a funcionalidade, acrescentando o mecanismo da barra de rolagem. Será utilizado num campo texto? Será utilizado num treeview? Bom, ele não precisa (nem pode) saber!&lt;br /&gt;&lt;br /&gt;Por quê eu digo que "nem pode" saber? Porque se ele tiver um conhecimento, uma referência à classe que ele vai decorar, ele vai ficar amarrado a esta classe! Caso você precise agora decorar uma tabela com barra de rolagem, a classe decoradora terá que ser alterada também, para incluir uma nova referência ao objeto tabela. E isso é ruim, muito ruim! Todo novo objeto a ser decorado com barra de rolagem demandará manutenção no código da classe decoradora! Além do mais, isso fere um dos princípios mais básicos das &lt;span style="font-weight: bold;"&gt;boas práticas&lt;/span&gt; da Orientação a Objetos: o &lt;span style="font-weight: bold;"&gt;Acoplamento&lt;/span&gt;, isto é, o grau em que uma classe conhece outra classe. Devemos buscar sempre o &lt;/span&gt;&lt;span style="font-weight: bold;font-family:arial;font-size:100%;"  &gt;Baixo Acoplamento&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;.&lt;br /&gt;&lt;br /&gt;Logo, o objeto decorador "barra de rolagem" só precisa saber que ele vai adicionar este mecanismo ao objeto. Precisa de barra de rolagem num campo texto? Basta fazer campo.add(barraDeRolagem); agora eu preciso em uma tabela... Ok, basta fazer tabela.add(barraDeRolagem); o decorador sofreu alguma alteração no código? Absolutamente &lt;/span&gt;&lt;span style="font-weight: bold;font-family:arial;font-size:100%;"  &gt;nenhuma&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;!&lt;br /&gt;&lt;br /&gt;Utilizando o exemplo do objeto Pizza que deverá ser decorado com Condimentos, obteremos o seguinte: tanto Pizza quanto Condimentos serão produtos alimentícios, dos quais eu vou querer saber o preço e descrição. Teremos:&lt;/span&gt;&lt;span style="font-family:arial,helvetica;"&gt;&lt;span style=""&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span style="color: rgb(0, 0, 0);font-family:arial;font-size:100%;"  &gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="font-family:courier new;"&gt;public interface ProdutoAlimenticio {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  public double getCusto();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  public String getDescricao();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;O meu Decorator também será do gênero produto alimentício (queijo, orégano, etc), logo, vai implementar a interface acima. Se eu pedir a descrição dos condimentos da pizza, precisarei imprimir "Queijo, Orégano, Calabreza, etc", ou seja, sobrescrevo o &lt;span style="font-weight: bold;"&gt;getDescricao()&lt;/span&gt; para concatenar com vírgulas. Logo, teremos:&lt;/span&gt;&lt;span style="font-family:arial,helvetica;"&gt;&lt;span style=""&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:100%;" &gt;&lt;pre&gt;&lt;span style="font-family:courier new;"&gt;public abstract class CondimentoDecorator&lt;br /&gt;        implements ProdutoAlimenticio {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public abstract String getDescricaoDoComplemento();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public String getDescricao() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        return ", " + getDescricaoDoComplemento();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;A classe Pizza deveria implementar a interface &lt;span style="font-weight: bold;"&gt;ProdutoAlimenticio&lt;/span&gt;, porém, vou adicionar uma camada intermediária, entre Pizza e ProdutoAlimenticio, com o intuito de flexibilizar a adição de novos pratos além de Pizza, como por exemplo HotDog. Vou chamar esta classe de &lt;span style="font-weight: bold;"&gt;Refeição&lt;/span&gt;, e veremos na prática como isto vai facilitar o reaproveitamento de código, o que é, aliás, uma das grandes vantagens da Orientação a Objetos.&lt;br /&gt;&lt;br /&gt;Portanto, a classe &lt;span style="font-weight: bold;"&gt;Refeição&lt;/span&gt; deverá implementar a interface &lt;span style="font-weight: bold;"&gt;ProdutoAlimenticio&lt;/span&gt;, mas ainda será uma classe &lt;span style="font-weight: bold;"&gt;abstrata&lt;/span&gt;, pois ela ainda não sabe informar o custo da refeição - &lt;span style="font-weight: bold;"&gt;getCusto()&lt;/span&gt; - o que vai ser responsabilidade de suas subclasses, até porque este custo vai ser um para Pizza e outro para HotDog, etc.&lt;br /&gt;&lt;br /&gt;Note que na classe Refeição&lt;span style="font-weight: bold;"&gt; não há&lt;/span&gt; qualquer referência a decoradores ou qualquer outro objeto que não interessa a ela. Tudo o que a classe &lt;span style="font-weight: bold;"&gt;Refeição&lt;/span&gt; sabe é que ela &lt;span style="font-weight: bold;"&gt;é um&lt;/span&gt; Produto Alimentício, que refeições têm um custo e uma descrição, e que refeições podem adicionar complementos - que, por sua vez, também serão Produtos Alimentícios. Logo, a classe Refeicao.java fica assim:&lt;br /&gt;&lt;pre&gt;&lt;span style="font-family:courier new;"&gt;public abstract class Refeicao&lt;br /&gt;        implements ProdutoAlimenticio{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    private String descricao;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    private double custo;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    protected abstract double getPrecoDaRefeicao();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    // Construtor da classe com String como parâmetro &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    protected Refeicao(String descricao){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        this.descricao = descricao;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        this.custo = getPrecoDaRefeicao();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public double getCusto() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        return custo;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public String getDescricao() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        return descricao;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public void add(ProdutoAlimenticio complemento) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        custo += complemento.getCusto();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        descricao += complemento.getDescricao();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;O que o método &lt;span style="font-weight: bold;"&gt;add&lt;/span&gt; acima faz, é simplesmente incrementar o custo da própria refeição com o custo de seu complemento, e da mesma forma, concatenar sua descrição com a descrição do complemento. Note que este método recebe um &lt;span style="font-weight: bold;"&gt;ProdutoAlimenticio&lt;/span&gt; como parâmetro; é tudo o que a refeição precisa saber - que ela pode adicionar complementos alimentícios. E só!&lt;br /&gt;&lt;br /&gt;Agora vamos implementar uma &lt;span style="font-weight: bold;"&gt;classe concreta de Decorator&lt;/span&gt;, por exemplo, &lt;span style="font-weight: bold;"&gt;Queijo&lt;/span&gt;. Você concorda comigo que &lt;span style="font-weight: bold;"&gt;Queijo&lt;/span&gt; poderá decorar tanto &lt;span style="font-weight: bold;"&gt;Pizzas&lt;/span&gt; quanto &lt;span style="font-weight: bold;"&gt;HotDogs&lt;/span&gt;? E que poderá decorar pratos que ainda nem foram criados? Que, se amanhã o cliente inventar um novo prato, e precisar decorá-lo com &lt;span style="font-weight: bold;"&gt;Queijo&lt;/span&gt;, este decorador deverá ser capaz de atendê-lo? Ou seja, está bastante evidente que na classe &lt;span style="font-weight: bold;"&gt;Queijo &lt;/span&gt;NÃO poderá haver referências a pratos, nem a pizzas, nem a refeições. Até porque, na classe &lt;span style="font-weight: bold;"&gt;CondimentoDecorator.java&lt;/span&gt; acima, a regra de concatenar sua descrição com vírgula já foi implementada. Logo, para a classe&lt;span style="font-weight: bold;"&gt; Queijo.java&lt;/span&gt; sobrou apenas informar o seu custo e sua descrição - responsabilidades pertinentes apenas à classe Queijo e à mais ninguém! Portanto, &lt;span style="font-weight: bold;"&gt;Queijo.java&lt;/span&gt; fica apenas assim:&lt;pre&gt;&lt;span style="font-family:courier new;"&gt;public class Queijo extends CondimentoDecorator {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public double getCusto() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        return 5;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public String getDescricaoDoComplemento() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        return "Queijo";&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;Ou seja, &lt;span style="font-weight: bold;"&gt;a classe Queijo é um CondimentoDecorator&lt;/span&gt;; e Queijo informa seu custo e sua descrição. Você sequer precisa descobrir quais métodos implementar na classe Queijo! Como &lt;span style="font-weight: bold;"&gt;Queijo extends CondimentoDecorator&lt;/span&gt;, a própria &lt;span style="font-weight: bold;"&gt;compilação&lt;/span&gt; te informa que você &lt;span style="font-weight: bold;"&gt;precisa&lt;/span&gt; implementar o &lt;span style="font-weight: bold;"&gt;método abstrato getDescricaoDoComplemento()&lt;/span&gt;; e que você &lt;span style="font-weight: bold;"&gt;precisa&lt;/span&gt; implementar o &lt;span style="font-weight: bold;"&gt;método abstrato getCusto() &lt;/span&gt;, uma vez que &lt;span style="font-weight: bold;"&gt;CondimentoDecorator&lt;/span&gt; não o implementou de &lt;span style="font-weight: bold;"&gt;ProdutoAlimenticio&lt;/span&gt;. Isto é, não tem como errar! É tão fácil adicionar novos condimentos que iremos adicionar mais um: &lt;span style="font-weight: bold;"&gt;Calabreza.java :&lt;/span&gt;&lt;pre&gt;&lt;span style="font-family:courier new;"&gt;public class Calabreza extends CondimentoDecorator {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public double getCusto() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        return 7;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public String getDescricaoDoComplemento() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        return "Calabreza";&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;Agora vamos implementar a classe &lt;span style="font-weight: bold;"&gt;Pizza&lt;/span&gt;. Adivinha o que sobrou para ser implementado em Pizza? Exato! Apenas a &lt;span style="font-weight: bold;"&gt;responsabilidade&lt;/span&gt; do que é de &lt;span style="font-weight: bold;"&gt;Pizza&lt;/span&gt;, ou seja, assim como Queijo e Calabreza, a classe &lt;span style="font-weight: bold;"&gt;Pizza &lt;/span&gt;só precisa informar seu &lt;span style="font-weight: bold;"&gt;custo&lt;/span&gt; e sua &lt;span style="font-weight: bold;"&gt;descrição&lt;/span&gt;! Aqui eu vou delegar ao &lt;span style="font-weight: bold;"&gt;construtor&lt;/span&gt; da classe &lt;span style="font-weight: bold;"&gt;Pizza&lt;/span&gt; a atribuição da descrição, certo? Só para permitir ao Cliente fazer:  &lt;span style="font-weight: bold;"&gt;Pizza  marguerita  = new Pizza("Marguerita")&lt;/span&gt;  ou   &lt;span style="font-weight: bold;"&gt;Pizza  simples  = new Pizza("Mussarela")&lt;/span&gt;, etc. Logo, a classe &lt;span style="font-weight: bold;"&gt;Pizza.java&lt;/span&gt; fica apenas assim:&lt;pre&gt;&lt;span style="font-family:courier new;"&gt;public class Pizza extends Refeicao {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    //Construtor atribui a descrição&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public Pizza(String descricao) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        super(descricao);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public double getPrecoDaRefeicao() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        return 10;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;Da mesma forma, &lt;span style="font-weight: bold;"&gt;Pizza é um&lt;/span&gt;a &lt;span style="font-weight: bold;"&gt;Refeição&lt;/span&gt;. Aqui também a &lt;span style="font-weight: bold;"&gt;compilação&lt;/span&gt; te informa o quê é preciso implementar. Caso você se esqueça de algo (ou algum colega novato na equipe...) será possível identificar o problema &lt;span style="font-weight: bold;"&gt;em tempo de compilação &lt;/span&gt;-&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;o que torna o nosso código muito mais resistente a falhas! Importante perceber também que &lt;span style="font-weight: bold;"&gt;Pizza.java não tem referência&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;a nenhum &lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-family:arial;font-size:100%;"  &gt;decorador&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;. Claro! Nem poderia! Iria ter referência a &lt;span style="font-weight: bold;"&gt;qual&lt;/span&gt; decorador? Queijo? Aqui, da forma como está feito, caso o Cliente crie um novo decorador (orégano, por exemplo), tudo o que eu preciso fazer é criar uma nova classe Oregano.java. Só isso! A classe Pizza.java (nem qualquer outra) não vai sofrer nenhuma alteração.&lt;br /&gt;&lt;br /&gt;Bom, vamos testar o projeto numa classe Executavel.java, que contenha um método main():&lt;br /&gt;&lt;pre&gt;&lt;span style="font-family:courier new;"&gt;public class Executavel {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public static void main(String[] args) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        Pizza p = new Pizza("Pizza Completa");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        p.add(new Queijo());&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        p.add(new Calabreza());&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        System.out.println("Descricao: "+p.getDescricao());&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        System.out.println("Total:  R$ "+p.getCusto());&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;Pronto! Tudo o que eu preciso fazer para decorar o objeto Pizza com um novo comportamento é passar o Decorator como parâmetro ao método add(). Note que, como este método precisa de um &lt;span style="font-weight: bold;"&gt;ProdutoAlimenticio&lt;/span&gt;, e &lt;span style="font-weight: bold;"&gt;Pizza é um ProdutoAlimenticio&lt;/span&gt;, eu poderia fazer:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Pizza pizza = new Pizza("Pizza Dupla");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;pizza.add(new  Pizza(""));&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;Como exercício, fica pra você a&lt;/span&gt;&lt;span&gt; tarefa de criar um novo prato&lt;span style="font-weight: bold;"&gt; HotDog.java&lt;/span&gt; e um novo&lt;/span&gt;&lt;span&gt; decorador para o complemento&lt;span style="font-weight: bold;"&gt; Oregano.java&lt;/span&gt;, e acrescentar orégano à Pizza já existente, e também reaproveitar Queijo e Calabreza para adicionar ao HotDog. (Abaixo está a solução)&lt;pre&gt;&lt;span style="font-family:courier new;"&gt;Tudo se resume a isso:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public class HotDog extends Refeicao {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public HotDog(String descricao) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        super(descricao);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public double getPrecoDaRefeicao() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        return 9;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public class Oregano extends CondimentoDecorator {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public double getCusto() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        return 2;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public String getDescricaoDoComplemento() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        return "Orégano";&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public class Executavel {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public static void main(String[] args) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        Pizza p = new Pizza("Pizza");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        p.add(new Queijo());&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        p.add(new Calabreza());&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        p.add(new Oregano());&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        HotDog dog = new HotDog("Hot Dog");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        dog.add(new Queijo());&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        dog.add(new Calabreza());&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        System.out.println("Descricao: "+p.getDescricao());&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        System.out.println("Total:  R$ "+p.getCusto());&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        System.out.println("Descricao: "+dog.getDescricao());&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        System.out.println("Total:  R$ "+dog.getCusto());&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;span&gt;Bem, espero que tenham gostado! Qualquer dúvida deixe uma mensagem que terei o maior prazer em respondê-la! Também escrevam para enviar sugestões. Pretendo colocar exemplos bem explicativos de todos os 23 padrões do GoF, que é um assunto obrigatório para quem quiser programar orientado a objetos, e onde ainda vejo muita deficiência por aí...  Abraços.&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7837967930470422637-4960834678481116605?l=marconems.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://marconems.blogspot.com/feeds/4960834678481116605/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://marconems.blogspot.com/2010/05/decorator.html#comment-form' title='5 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7837967930470422637/posts/default/4960834678481116605'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7837967930470422637/posts/default/4960834678481116605'/><link rel='alternate' type='text/html' href='http://marconems.blogspot.com/2010/05/decorator.html' title='Decorator'/><author><name>Marcone</name><uri>http://www.blogger.com/profile/13438429290931637472</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_2dT5MiuZ4Y0/S_59ih5VjtI/AAAAAAAAAAM/1u7SGTtzn1g/S220/java.jpg'/></author><thr:total>5</thr:total></entry></feed>
