NOTAS DO PROFESSOR DR.

JACQUES PHILIPPE SAUVÉ COM TEXTO FORMATADO POR JOBSON M.

PADRÕES DE PROJETOS JAVA

Sumário
Expert ...................................................................................................................................................... 3 Problema ....................................................................................................................................... 3 Solução........................................................................................................................................... 3 Exemplo ......................................................................................................................................... 3 Discussão....................................................................................................................................... 4 Consequências ............................................................................................................................. 5 Também conhecido como .......................................................................................................... 5 Creator .................................................................................................................................................... 6 Problema ....................................................................................................................................... 6 Solução........................................................................................................................................... 6 Exemplo ......................................................................................................................................... 6 Discussão....................................................................................................................................... 7 Consequências ............................................................................................................................. 7 Baixo Acoplamento ......................................................................................................................... 8 Problema ....................................................................................................................................... 8 Solução........................................................................................................................................... 8 Exemplo ......................................................................................................................................... 8 Discussão....................................................................................................................................... 9 Consequências ........................................................................................................................... 13 Alta Coesão............................................................................................................................................ 15 Problema ..................................................................................................................................... 15 Solução......................................................................................................................................... 15 Exemplo ....................................................................................................................................... 15 Discussão..................................................................................................................................... 16 Consequências ........................................................................................................................... 19 Controller .............................................................................................................................................. 20 Problema ..................................................................................................................................... 20 Solução......................................................................................................................................... 20 Exemplo ....................................................................................................................................... 20 Discussão..................................................................................................................................... 21 Consequências ........................................................................................................................... 23 Responsabilidades, Role Playing e Cartões CRC ...................................................................... 23

Página 3 de 24 Expert Problema  Qual é o princípio mais fundamental para atribuir responsabilidades? Solução  Atribuir uma responsabilidade ao expert de informação .a classe que possui a informação necessária para preencher a responsabilidade Exemplo     No estudo de caso. escolhemos a classe que possui a informação necessária para determinar o total Considere uma parte do modelo conceitual:   Qual é a informação necessária?  Precisamos conhecer (ter acesso a) todos os LinhaDetalheVenda  Qual é information expert?  É a classe Venda Podemos agora fazer parte do diagrama de colaboração e do diagrama de classes  Ainda não terminamos. alguma classe precisa saber o total de uma venda Podemos dizer isso sobre a forma de uma responsabilidade:  Quem deveria ser reponsável pelo conhecimento do total de uma venda? Pelo padrão Expert. Qual informação é necessária para determinar o subtotal para um item (uma linha de detalhe)? .

em 3 classes diferentes Mensagens são usadas para estabelecer as colaborações O resultado final é diferente do mundo real  No mundo real.Página 4 de 24  Precisamos de LinhaDeVenda.quantidade e de EspecificaçãoDeProduto.preço  Quem é o information expert?  É a classe LinhaDeVenda Chegamos aos seguintes diagramas:    Qual é o information expert para saber o preço de um produto?  É EspecificaçãoDeProduto Chegamos aos seguintes diagramas: Discussão     É o padrão mais usado de todos para atribuir responsabilidades A informação necessária frequentemente está espalhada em vários objetos  Portanto. tem muitos experts parciais  Exemplo: determinar o total de uma venda requer a colaboração de 3 objetos. uma venda não calcula seu próprio total .

faz" "Animação" "Eu mesmo faço" "Colocar os serviços junto aos atributos que eles manipulam" . não queremos atribuir essa responsabilidade ao Caixa ou ao TPDV! No mundo de software. já que os objetos fazem tudo que é relacionado à sua própria informação Também conhecido como      "Colocar as responsabilidades com os dados" "Quem sabe. já que objetos usam sua própria informação para cumprir suas responsabilidades  Leva a fraco acoplamento entre objetos e sistemas mais robustos e fáceis de manter Leva a alta coesão.Página 5 de 24    Isso seria feito por uma pessoa (se não houvesse software) Mas no mundo de software. coisas inertas (ou até conceitos como uma venda) podem ter responsabilidades: Tudo está vivo! Consequências   A encapsulação é mantida.

.. contém.Página 6 de 24 Creator Problema  Quem deve criar novas instâncias de uma classe? Solução    Atribuir à classe B a responsabilidade de criar instância da classe A se uma das seguintes condições se aplicar:  B agrega objetos da classe A  B contém objetos da classe A  B registra instâncias da classe A  B usa muito objetos da classe A  B possui os dados usados para inicializar A B é um criador (creator) de objetos da classe A Se mais de uma opção se aplica. . instâncias de LinhaDetalheVenda Considere o modelo conceitual parcial abaixo:   Venda agrega instâncias de LinhaDetalheVenda e é portanto um bom candidato para criar as instâncias Chegamos aos seguintes diagramas: . escolha o B que agregue ou contenha objetos da classe A Exemplo    No estudo de caso. precisamos achar alguém que agrega. quem deveria criar uma instância de LinhaDetalheVenda? Pelo padrão Creator.

já que o objeto criado deve normalmente ser visível ao criador.Página 7 de 24 Discussão    Escolhemos um criador que deve estar conectado ao objeto criado. de qualquer forma. depois da criação Isso leva a fraco acoplamento Exemplo de criador que possui os valores de inicialização  Uma instância de Pagamento deve ser criada  A instância deve receber o total da venda  Quem tem essa informação? Venda  Venda é um bom candidato para criar objetos da classe Pagamento Consequências  Fraco acoplamento. . depois da criação.

já que depende da presença de outras classes Solução  Atribuir responsabilidades de forma a minimizar o acoplamento Exemplo  Considere o seguinte diagrama parcial de classes no estudo de caso    Suponha que temos que criar um Pagamento e associá-lo a uma Venda Que classe deveria ter essa responsabilidade? Alternativa 1: No mundo real. um TPDV "registra" um pagamento e o padrão Creator sugere que TPDV poderia criar Pagamento  TPDV deve então passar o pagamento para a Venda  Veja o resultado abaixo  Alternativa 2: Criar o Pagamento com Venda e associá-lo à Venda  Veja o resultado abaixo . temos os seguintes problemas:  Mudanças a uma classe relacionada força mudanças locais à classe  A classe é mais difícil de entender isoladamente  A classe é mais difícil de ser reusada.Página 8 de 24 Baixo Acoplamento Problema     Como minimizar dependências e maximizar o reuso? O acoplamento é uma medida de quão fortemente uma classe está conectada. uma classe não é dependente de muitas outras classes Com uma classe possuindo forte acoplamento. possui conhecimento ou depende de outra classe Com fraco acoplamento.

objeto retornado pelo método  X é uma subclasse direta ou indireta de Y  X implementa a interface Y A herança é um tipo de acoplamento particularmente forte  Uma seção futura esmiuça o assunto Não se deve minimizar acoplamento criando alguns poucos objetos monstruosos (God classes)  Exemplo: todo o comportamento numa classe e outras classes usadas como depósitos passivos de informação Tipos de acoplamentos (do menos ruim até o pior)  Acoplamento de dados  Acoplamento de controle  Acoplamento de dados globais  Acoplamento de dados internos Acoplamento de dados  Situações  Saída de um objeto é entrada de outro  Uso de parâmetros para passar itens entre métodos  Ocorrência comum:  Objeto a passa objeto x para objeto b  Objeto x e b estão acoplados  Uma mudança na interface de x pode implicar em mudanças a b  Exemplo: . a alternativa 2 tem menos acoplamento (TPDV não está acoplado a Pagamento)  Dois padrões (Creator e Low Coupling) sugeriram diferentes soluções  Minimizar acoplamento ganha Discussão       Minimizar acoplamento é um dos princípios de ouro do projeto OO Acoplamento de manifesta de várias formas:  X tem um atributo que referencia uma instância de Y  X tem um método que referencia uma instância de Y  Pode ser parâmetro.Página 9 de 24  Supondo que a Venda deva ter conhecimento do pagamento (depois da criação) de qualquer jeito. variável local.

façaAlgo(Object dados).. } } // etc. x. vamos ver os problemas class ListaOrdenada { Object[] elementosOrdenados = new Object[tamanhoAdequado]. long matrícula2 = elementosOrdenados[k]. public void add(Aluno x) { // código não mostrado long matrícula1 = x.getMatrícula()..add(novoAluno). ListaOrdenada listaDeAlunos = new ListaOrdenada(). listaDeAlunos. y  Exemplo: ordenação de registros de alunos por matrícula e nome class Aluno { String nome. long matrícula. if(matrícula1 < matrícula2) { // faça algo } else { // faça outra coisa } }  O problema da solução anterior é que há forte acoplamento . // dados e x estão acoplados // (se interface de dados mudar x terá que mudar) // mais código } } o Exemplo pior:  Objeto a passa objeto x para objeto b  x é um objeto composto ou agregado (contém outro(s) objeto(s))  Objeto b deve extrair objeto y de dentro de x  Há acoplamento entre b. public String getNome() { return nome.). //etc.Página 10 de 24 class Servidor { public void mensagem(MeuTipo x) { // código aqui x.getMatrícula(). Aluno novoAluno = new Aluno(. } public long getMatrícula() { return matrícula. representação interna de x.  Agora.

Página 11 de 24  ListaOrdenada sabe muita coisa de Aluno  O fato de que a comparação de alunos é feito com a matrícula  O fato de que a matrícula é obtida com getMatrícula()  O fato de que matrículas são long (representação de dados)  Como comparar matrículas (com <)  O que ocorre se mudarmos qualquer uma dessas coisas? Solução 2: mande uma mensagem para o próprio objeto se comparar com outro  class ListaOrdenada { Object[] elementosOrdenados = new Object[tamanhoAdequado]. public boolean equal(Object outro). public void add(Comparable x) { // código não mostrado if(x. public void add(Aluno x) { // código não mostrado if(x. } class Aluno implements Comparable { public boolean lessThan(Object outro) { // compare registro de aluno com outro } } class ListaOrdenada { Object[] elementosOrdenados = new Object[tamanhoAdequado].lessThan(elementosOrdenados[K])) { // faça algo } else { // faça outra coisa } } .lessThan(elementosOrdenados[K])) { // faça algo } else { // faça outra coisa } }    Reduzimos o acoplamento escondendo informação atrás de um método Problema: ListaOrdenada só funciona com Aluno Solução 3: use interfaces para desacoplar mais ainda Interface Comparable { public boolean lessThan(Object outro). public boolean greaterThan(Object outro).

setLampada(Lampada.Página 12 de 24  Em C++. o Solução: decompor a operação em múltiplas operações primitivas class Lampada { public void on() { // liga lampada } public void off() { // desliga lampada } public void pisca() { // pisca } } Lampada lampada = new Lampada(). lampada. o Ocorrência comum:  Objeto a manda mensagem para objeto b  b retorna informação de controle para a  Exemplo: retorno de código de erro class Teste { public int printFile(File toPrint) { . public void setLampada(int valor) { if(valor == ON) { // liga lampada } else if(valor == 1) { // desliga lampada } else if(valor == 2) { // pisca } } } Lampada lampapa = new Lampada().pisca().setLampada(2).ON). teria outras soluções  Apontador de função  Apontador de função com tipos genéricos (templates) Acoplamento de controle  Passar flags de controle entre objetos de forma que um objeto controle as etapas de processamento de outro objeto  Ocorrência comum:  Objeto a manda uma mensagem para objeto b  b usa um parâmetro da mensagem para decidir o que fazer o class Lampada { public static final ON = 0. lampada.on(). lampada. lampada.

etc. if(resultado == CORRUPTFLAG) { // oh! oh! } else if(resultado == -243) { // etc.printFile(miniTeste).Página 13 de 24 if(toPrint está corrompido ) { return CORRUPTFLAG. } // etc. umTeste. } // etc. int resultado = umTese. } } try { Teste umTeste = new Teste(). etc. etc.printFile(miniTeste). } catch(PrintException printError) { // faça algo }   Acoplamento de dados globais  Dois ou mais objetos compartilham estruturas de dados globais  É um acoplamento muito ruim pois está escondido  Uma chamada de método pode mudar um valor global e o código não deixa isso aparente  Um tipo de acoplamento muito ruim Acoplamento de dados internos  Um objeto altera os dados locais de um outro objeto  Ocorrência comum:  Friends em C++  Dados protected ou públicos de java  Use com cuidado! Consequências . } } Teste umTeste = new Teste(). o Solução: use exceções class Teste { public int printFile(File toPrint) throws PrintExeception { if(toPrint está corrompido ) { throw new PrintExeception().

Página 14 de 24    Uma classefracamente acoplada não é afetada (ou pouco afetada) por mudanças em outras classes Simples de entender isoladamente Reuso mais fácil .

Página 15 de 24 Alta Coesão Problema     Como gerenciar a complexidade? A coesão mede quão relacionados ou focados estão as responsabilidades da classe  Também chamado coesão funcional (ver à frente) Uma classe com baixa coesão faz muitas coisas não relacionadas e leva aos seguintes problemas:  Difícil de entender  Difícil de reusar  Difícil de manter  "Delicada": constantemente sendo afetada por outras mudanças Uma classe com baixa coesão assumiu responsabilidades que pertencem a outras classes e deveriam ser delagadas Solução  Atribuir responsabilidades que mantenham alta coesão Exemplo   Mesmo exemplo usado para Low Coupling Na primeira alternativa. TPDV assumiu uma responsabilidade de efetuar um pagamento (método façaPagamento())    Até agora. não há problema Mas suponha que o mesmo ocorra com várias outras operações de sistema  TPDV vai acumular um monte de métodos não muito focados  Resultado: baixa coesão A segunda alternativa delega façaPagamento() para a classe Venda  Mantém maior coesão em TPDV .

. case OFF: . } public static int média(Vector números) { // .. }  Coesão lógica  Módulo faz um conjunto de funções relacionadas.Página 16 de 24 Discussão    Alta coesão é outro princípio de ouro que deve ser sempre mantido em mente durante o projeto Tipos de coesão entre módulos  Coincidental (pior)  Lógico  Temporal  Procedural  De comunicação  Sequencial  Funcional (melhor) Coesão coincidental  Há nenhuma (ou pouca) relação construtiva entre os elementos de um módulo  No linguajar OO:  Um objeto não representa nenhum conceito OO  Uma coleção de código comumente usado e herdado através de herança (provavelmente múltipla) class Angu { public static int acharPadrão(String texto.... String padrão) { // . } public static outputStream abreArquivo(string nomeArquivo) { // . uma das quais é escolhida através de um parâmetro ao chamar o módulo  Semelhante a acoplamento de controle  Cura: quebrar em métodos diferentes public void faça(int flag) { switch(flag) { case ON: // coisas para tratar de ON break. } } class Xpto extends Angu { // quer aproveitar código de Angu ....

400".0. } o Cura: depender de construtores e destrutores class Xpto { public Xpto() { this. windowSize = "200. } } o Outro exemplo: arquivo de configuração típico [Macintosh] EquationWindow=146.0. this. case COR: // coisas para tratar de COR break. xpto. case FECHAR: // coisas para tratar de FECHAR break.tamanho = 12.Página 17 de 24 }  // coisas para tratar de OFF break. xpto. } Coesão temporal  Elementos estão agrupados no mesmo módulo porque são processados no mesmo intervalo de tempo  Exemplos comuns:  Método de inicialização que provê valores defaults para um monte de coisas diferentes  Método de finalização que limpa as coisas antes de terminar procedure inicializaDados() { font = "times".406.661 SpacingWindow=0.localização = "/usr/local/lib/java".171.tamanho = 12.nome = "desligado".nome = "desligado".localização = "/usr/local/lib/java". xpto. this.0 [Spacing] LineSpacing=150% MatrixRowSpacing=150% MatrixColSpacing=100% SuperscriptHeight=45% .

B Number=Times [Sizes] Full=12pt Script=7pt ScriptScript=5pt Symbol=18pt SubSymbol=12pt  Coesão procedural  Associa elementos de acordo com seus relacionamentos procedurais ou algorítmicos  Um módulo procedural depende muito da aplicação sendo tratada .5pt PrimeHeight=45% [General] Zoom=200 CustomZoom=150 ShowAll=0 Version=2.5pt SubFractBarThick=0.25pt FenceOver=1pt SpacingFactor=100% MinGap=8% RadicalGap=2pt EmbellGap=1.I UCGreek=Symbol Symbol=Symbol Vector=Times.01 OptimalPrinter=1 MinRect=0 ForceOpen=0 ToolbarDocked=1 ToolbarShown=1 ToolbarDockPos=1 [Fonts] Text=Times Function=Times Variable=Times.I LCGreek=Symbol.Página 18 de 24 SubscriptDepth=25% LimHeight=25% LimDepth=100% LimLineSpacing=100% NumerHeight=35% DenomDepth=100% FractBarOver=1pt FractBarThick=0.

Página 19 de 24    Junto com a aplicação. o módulo parece estranho e muito difícil de entender  "O que está acontecendo aqui!!!????!!"  Não pode entender o módulo sem entender o programa e as condições que existem quando o módulo é chamado  Cura: reprojete o sistema Coesão de comunicação  Todas as operações de um módulo operam no mesmo conjunto de dados e/ou produzem o mesmo tipo de dado de saída  Cura: isole cada elemento num módulo separado  "Não deveria" ocorrer em sistemas OO usando polimorfismo (classes diferentes para fazer tratamentos diferentes nos dados) Coesão sequencial  A saída de um elemento de um módulo serve de entrada para o próximo elemento  Cura: decompor em módulos menores Coesão funcional (a melhor)  Um módulo tem coesão funcional se as operações do módulo puderem ser descritas numa única frase de forma coerente  Num sistema OO:  Cada operação na interface pública do objeto deve ser funcionalmente coesa  Cada objeto deve representar um único conceito coeso  Exemplo: um objeto que esconde algum conceito ou estrutura de dados ou recurso e onde todos os métodos são relacionados por um conceito ou estrutura de dados ou recurso  Meyer chama isso de "information-strength module"  Consequências     Melhor claridade e facilidade de compreensão do projeto Simplificação da manutenção Frequentemente vai mão na mão com acoplamento fraco Com granularidade baixa e funcionalidade bem focada. o módulo parece razoável  Sem este contexto. aumenta o reuso .

temos as seguintes alternativas: . normalmente chamado "<NomeDoUseCase>Handler" (use case controller) Exemplo  No estudo de caso. há várias operações de sistema:  Quem deveria ser o controlador para os eventos do sistema?  Pelo padrão Controller. o papel de uma pessoa) que poderia estar envolvido na tarefa (role controller)  Representa um handler artificial de todos os eventos do sistema para um Use Case particular.Página 20 de 24 Controller Problema     Quem deveria receber a responsabilidade de tratar eventos do sistema? Um evento do sistema é um evento de alto nível gerado por um ator externo Estão associados a operações do sistema que já vimos nos Diagramas de Sequência do Sistema Exemplo do estudo de caso: Caixa pressiona "Fim de venda" Solução   Use um controlador  Um controlador é um objeto que não é de interface GUI responsável pelo tratamento de eventos do sistema  Um controlador define métodos para as operações do sistema Atribuir a responsabilidade pelo tratamento de eventos do sistema a uma classe de acordo com uma das alternativas abaixo:  Representa o "sistema" como um todo (facade controller)  Representa o negócio ou organização como um todo (facade controller)  Representa algo no mundo real que é ativo (por exemplo.

"View". o mesmo controlador deve ser usado para todas as operações de um mesmo Use Case de forma a manter a informação de estado do Use Case  A informação de estado pode ser útil para detectar sequências erradas de eventos de sistema  Exemplo: façaPagamento() antes de fimDeVenda() Não coloque toda a inteligência no controlador  Delegue para outros objetos. teríamos:  Discussão     De forma geral.para manter coesão Use um Handler artificial quando as outras alternativas exibem acoplamento alto ou coesão baixa  Quando está surgindo um "God class"  Usado em sistemas mais complexos Observe que classes "Window".: Caixa  Representa um handler artificial .. se fosse TPDV. "Application"...: CompraItemHandler A escolha particular depende de fatores discutidos na seção Discussão  Por exemplo.Página 21 de 24  Representa o "sistema": TPDV  Representa o negócio ou organização: Loja  Representa algo no mundo real . "Document" não devem ser controladores  Tais classes podem receber o evento e delegá-lo ao controlador  Não se deve colocar business logic num objeto de interface com o usuário  Um design correto seria: . "Applet"..

Página 22 de 24 o Um design incorreto seria: .

Wilkerson e Wiener. Role Playing e Cartões CRC      Embora não faça parte de UML. Algumas pessoas acham que é melhor usar ferramentas gráficas em vez de CRC . já que o business logic não está nos objetos de interface  Exemplo: embutir o business logic num objeto de interface não permitiria fazer EAI (Enterprise Application Integration) Ajuda a verificar o sequenciamento das operações do sistema. CRC = Class-Responsibility-Collaborations CRC cards inventadas por Ward Cunningham e Kent Beck (Tektronix) Cartão CRC é um cartão pequeno (para só escrever o essencial) para cada classe Escreve-se o nome da classe. 1990.Página 23 de 24 o O Role Controller pode levar a um mau projeto  O fato de algo ser feito por uma pessoa no mundo real não necessariamente significa que isso é uma boa alternativa em software  É mais comum "dar vida aos objetos" (não animados) Consequências   Maior possibilidade de reuso. através do estado do controlador Responsabilidades. uma técnica chamada Cartões CRC é muito usada para atribuir responsabilidades durante o projeto. Wirfs-Brock. suas responsabilidades e colaborações  Só pense nas responsabilidades de alto nível    São desenvolvidos em pequenos grupos em que cada pessoa assume o papel (Role) de uma ou mais classes Mais detalhes aqui:  Designing Object-Oriented Software. Prentice Hall.

Página 24 de 24 .

Sign up to vote on this title
UsefulNot useful