k19 k51 design patterns em java
TRANSCRIPT
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 1/121
TREINAMENTOS
Design Patterns em Java
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 2/121
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 3/121
Design Patterns em Java
21 de dezembro de 2011
Sumário i
Sobre a K19 1
Seguro Treinamento 2
Termo de Uso 3
Cursos 4
1 Introdução 51.1 Sistemas Corporativos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51.2 Orientação a Objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51.3 Padrões de Projeto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2 Padrões de criação 72.1 Factory Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72.2 Exercícios de Fixação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112.3 Abstract Factory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132.4 Abstract Factory + Factory Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162.5 Exercícios de Fixação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.6 Exercícios Complementares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192.7 Builder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192.8 Exercícios de Fixação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232.9 Prototype . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262.10 Exercícios de Fixação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282.11 Singleton . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302.12 Exercícios de Fixação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312.13 Multiton (não GoF) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322.14 Exercícios de Fixação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332.15 Object Pool (não GoF) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352.16 Exercícios de Fixação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3 Padrões Estruturais 41
www.k19.com.br i
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 4/121
SUMÁRIO ii
3.1 Adapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413.2 Exercícios de Fixação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443.3 Bridge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463.4 Exercícios de Fixação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493.5 Composite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 513.6 Exercícios de Fixação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 543.7 Decorator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563.8 Exercícios de Fixação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 603.9 Facade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623.10 Exercícios de Fixação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 653.11 Front Controller (não GoF) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 673.12 Exercícios de Fixação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 683.13 Flyweight . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 693.14 Exercícios de Fixação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 723.15 Proxy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 743.16 Exercícios de Fixação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
4 Padrões Comportamentais 794.1 Command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 794.2 Exercícios de Fixação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 824.3 Iterator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 844.4 Exercícios de Fixação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 874.5 Mediator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 884.6 Exercícios de Fixação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 914.7 Observer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 944.8 Exercícios de Fixação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
4.9 State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 994.10 Exercícios de Fixação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1014.11 Strategy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1024.12 Exercícios de Fixação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1054.13 Template Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1064.14 Exercícios de Fixação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1094.15 Visitor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1104.16 Exercícios de Fixação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
ii www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 5/121
1 SUMÁRIO
Sobre a K19
A K19 é uma empresa especializada na capacitação de desenvolvedores de software. Sua equipeé composta por profissionais formados em Ciência da Computação pela Universidade de São Paulo(USP) e que possuem vasta experiência em treinamento de profissionais para área de TI.
O principal objetivo da K19 é oferecer treinamentos de máxima qualidade que relacionados àsprincipais tecnologiasutilizadas pelasempresas. Através dessestreinamentos, seus alunos se tornamcapacitados para atuar no mercado de trabalho.
Visando a máxima qualidade, a K19 mantém as suas apostilas em constante renovação e melho-ria, oferece instalações físicas apropriadas para o ensino e seus instrutores estão sempre atualizadosdidática e tecnicamente.
www.k19.com.br 1
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 6/121
SUMÁRIO 2
Seguro Treinamento
Na K19 o aluno faz o curso quantas vezes quiser!
Comprometida com o aprendizado e com a satisfação dos seus alunos, a K19 é a única que pos-sui o Seguro Treinamento. Ao contratar um curso, o aluno poderá refazê-lo quantas vezes desejarmediante a disponibilidade de vagas e pagamento da franquia do Seguro Treinamento.
As vagas não preenchidas até um dia antes do início de uma turma da K19 serão destinadas aoalunos que desejam utilizar o Seguro Treinamento. O valor da franquia para utilizar o Seguro Treina-mento é 10% do valor total do curso.
2 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 7/121
3 SUMÁRIO
Termo de Uso
Termo de Uso
Todo o conteúdo desta apostila é propriedade da K19 Treinamentos. A apostila pode ser utilizadalivremente para estudo pessoal . Além disso, este material didático pode ser utilizado como materialde apoio em cursos de ensino superior desde que a instituição correspondente seja reconhecida peloMEC (Ministério da Educação) e que a K19 seja citada explicitamente como proprietária do material.
É proibida qualquer utilização desse material que não se enquadre nas condições acima semo prévio consentimento formal, por escrito, da K19 Treinamentos. O uso indevido está sujeito àsmedidas legais cabíveis.
www.k19.com.br 3
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 8/121
SUMÁRIO 4
K01- Lógica de Programação
K11 - Orientação a Objetos em Java
K12 - Desenvolvimento Web com JSF2 e JPA2
K21 - Persistência com JPA2 e Hibernate
K22 - Desenvolvimento Web Avançado com JFS2, EJB3.1 e CDI
K23 - Integração de Sistemas com Webservices, JMS e EJB
K31 - C# e Orientação a Objetos
K32 - Desenvolvimento Web com ASP.NET MVC
T R E I N
A M E N
T O S
TREINAMENTOS
T R E I N AM E N T O S Conheça os nossos cursos
www.k19.com.br/cursos
4 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 9/121
INTRODUÇÃO
C A P
Í T U
L O
1Sistemas Corporativos
Dificilmente, uma empresa consegue sobreviver sem auxílio de ferramentas computacionais. Al-gumas organizações necessitam de ferramentas básicas como editores de texto, planilhas ou gerado-res de apresentação enquanto outras necessitam de ferramentas específicas (sistemas corporativos)que contemplem todos os processos administrativos da organização.
Em geral, a complexidade no desenvolvimento e na manutenção de um sistema corporativo éalta. Essa complexidade aumenta o custo e o tempo para desenvolvê-lo e mantê-lo.
Técnicas de programação como orientação a objetos, metodologias de gerenciamento comoscrum e ferramentas como Java podem diminuir o tempo e o dinheiro gastos na área de TI.
Orientação a Objetos
O paradigma de programação orientado a objetos estabelece princípios fundamentais referen-tes à organização de um software. Esses princípios podem diminuir consideravelmente o custo nodesenvolvimento e na manutenção de sistemas corporativos.
Abaixo, algumas características dos sistemas orientados a objetos:
• Modularidade
• Encapsulamento
• Polimorfismo
Hoje em dia, a orientação a objetos é o modelo de programação mais utilizado na modelagem desistemas corporativos.
Padrões de Projeto
Apesar de específicos, os sistemas corporativos possuem diversas características semelhantes.Consequentemente, muitos problemas se repetem em contextos distintos.
Suponha que um determinado problema ocorrerá em duzentos sistemas diferentes. Em cadasistema, esse problema pode ser resolvido de uma forma distinta. Então, globalmente, teríamos
duzentas soluções para o mesmo problema. Provavelmente, algumas soluções seriam melhores queoutras ou até mesmo uma delas melhor do que todas as outras.
www.k19.com.br 5
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 10/121
INTRODUÇÃO 6
Para não perder tempo e dinheiro elaborando soluções diferentes para o mesmo problema, po-deríamos escolher uma solução como padrão e adotá-la toda vez que o problema correspondenteocorrer. Além de evitar o retrabalho, facilitaríamos a comunicação dos desenvolvedores e o entendi-mento técnico do sistema.
Daí surge o conceito de padrão de projeto ou design pattern. Um padrão de projeto é umasolução consolidada para um problema recorrente no desenvolvimento e manutenção de softwareorientado a objetos.
A referência mais importante relacionada a padrões de projeto é o livro Design Patterns: Elements
of Reusable Object-Oriented Software (editora Addison-Wesley, 1995) dos autores Erich Gamma, Ri-chard Helm, Ralph Johnson e John Vlissides. Esses quatro autores são conhecidos como “Gang of Four”(GoF). Os diagramas UML apresentados nesta apostila são baseados nos diagramas desse livro.
Padrões GoF
Os padrões definidos no livro Design Patterns: Elements of Reusable Object-Oriented Software sãodenominados padrões GoF. Eles são classificados em três categorias: padrões de criação, estruturaise comportamentais.
6 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 11/121
P ADRÕES DE CRIAÇÃO
C A P
Í T U
L O
2Em um sistema orientado a objetos, a criação de certos objetos pode ser uma tarefa extrema-
mente complexa. Podemos destacar dois problemas relacionados a criação de objetos:
• definir qual classe concreta deve ser utilizada para criar o objeto;
• definir como os objetos devem ser criados e como eles se relacionam com outros objetos do
sistema.
Seguindo o princípio do encapsulamento, essa complexidade deve ser isolada. A seguir, mostra-remos padrões de projetos que podem ser adotados para encapsular a criação de objetos em diversassituações distintas.
Veja abaixo um resumo do objetivo de cada padrão de criação.
Factory Method Encapsular a escolha da classe concreta a ser utilizada na criação de objetos de umdeterminado tipo.
Abstract Factory Encapsular a escolha das classes concretas a serem utilizadas na criação dos obje-tos de diversas famílias.
Builder Separar o processo de construção de um objeto de sua representação e permitir a sua cri-ação passo-a-passo. Diferentes tipos de objetos podem ser criados com implementações dis-tintas de cada passo.
Prototype Possibilitar a criação de novos objetos a partir da cópia de objetos existentes.
Singleton Permitiracriaçãodeumaúnicainstânciadeumaclasseefornecerummodopararecuperá-la.
Multiton Permitir a criação de uma quantidade limitada de instâncias de determinada classe e for-necer um modo para recuperá-las.
Object Pool Possibilitar o reaproveitamento de objetos.
Factory Method
Objetivo: Encapsular a escolha da classe concreta a ser utilizada na criação de objetos de um de-
terminado tipo.
www.k19.com.br 7
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 12/121
P ADRÕES DE CRIAÇÃO 8
Exemplo prático
Considere um sistema bancário que precisa enviar mensagens aos seus clientes. Por exemplo,
após a realização de uma compra com cartão de crédito, uma mensagem contendo informaçõessobre a compra pode ser enviada ao cliente.
Se esse cliente for uma pessoa física, poderá optar pelo recebimento da mensagem através deemail ou SMS. Por outro lado, se for uma pessoa jurídica, poderá também receber a mensagem atra-vés de JMS (Java Message Service).
Figura 2.1: Recebimento de mensagem SMS após uma compra
Cada mecanismo de envio será implementado por uma classe. Podemos criar uma interface parapadronizar essas classes e obter polimorfismo entre seus objetos.
1 public interface E m i ss o r {
2 void envia(String mensagem);
3 }
Código Java 2.1: Emissor.java
1 p u b li c c l a ss EmissorSMS implements E m i ss o r {
2 p u b li c v o id e n v ia ( S t r i ng m e n s ag e m ) {3 System . out . println ( " E n vi a nd o p or S MS a m e ns a ge m : " );
4 System .out .println (mensagem );
5 }
6 }
Código Java 2.2: EmissorSMS.java
1 p u b li c c l a ss EmissorEmail implements E m i ss o r {
2 p u b li c v o id e n v ia ( S t r i ng m e n s ag e m ) {
3 System . out . println ( " E n vi a nd o p or e ma i l a m e ns a ge m : ");
4 System .out .println (mensagem );
5 }
6 }
Código Java 2.3: EmissorEmail.java
8 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 13/121
9 P ADRÕES DE CRIAÇÃO
1 p u b li c c l a ss EmissorJMS implements E m i ss o r {
2 p u b li c v o id e n v ia ( S t r i ng m e n s ag e m ) {
3 System . out . println ( " E n vi a nd o p or J MS a m e ns a ge m : " );
4 System .out .println (mensagem );
5 }
6 }
Código Java 2.4: EmissorJMS.java
Quando for necessário enviar um mensagem, podemos utilizar diretamente esses emissores.
1 E mi ss or e mi ss or = ne w EmissorSMS();
2 e mi ss or . e nv ia (" K 1 9 - T r e i na m e n to s " );
Código Java 2.5: Enviando uma mensagem por SMS
1 E mi ss or e mi ss or = ne w EmissorEmail();
2 e mi ss or . e nv ia (" K 1 9 - T r e i na m e n to s " );
Código Java 2.6: Enviando uma mensagem por email
1 E mi ss or e mi ss or = ne w EmissorJMS();
2 e mi ss or . e nv ia (" K 1 9 - T r e i na m e n to s " );
Código Java 2.7: Enviando uma mensagem por JMS
Utilizando essa abordagem, o código que deseja enviar uma mensagem referencia diretamenteas classes que implementam os mecanismos de envio. Para eliminar essa referência direta, podemosadicionar um intermediário entre o código que deseja enviar uma mensagem e as classes que imple-mentam os emissores. Esse intermediário será o responsável pela escolha da classe concreta a ser
utilizada para criar o tipo de emissor adequado.1 p u b li c c l a ss E m i s so r C r ea t o r {
2 p u b li c s t a ti c f i n al i n t S MS = ;
3 p u b li c s t a ti c f i n al i n t E MA I L = 1 ;
4 p u b li c s t a ti c f i n al i n t J MS = 2 ;
5
6 public E m i ss o r c r e at e ( in t t i p o De E m i ss o r ) {
7 if ( t i p o D eE m i s so r = = E m i s s or C r e a to r . S M S ) {
8 r e t ur n n e w EmissorSMS();
9 } e l s e i f ( t i p o D e Em i s s or = = E m i s so r C r ea t o r . E M A IL ) {
1 r e t ur n n e w EmissorEmail();
11 } e l s e i f ( t i p o D e Em i s s or = = E m i s so r C r ea t o r . J M S ) {
12 r e t ur n n e w EmissorJMS();
13 } else {
14 t h r ow n e w IllegalArgumentException( " T i p o d e e m i ss o r n ã o s u p o r t ad o ") ;
15 }16 }
17 }
Código Java 2.8: EmissorCreator.java
Especialização
Talvez, o sistema tenha que trabalhar com dois tipos diferentes de envio de mensagens: síncronoe assíncrono. Podemos especializar o criador de emissores, definindo subclasses.
1 p u b li c c l a ss EmissorAssincronoCreator extends E m i s so r C r ea t o r {2 public E m i ss o r c r e at e ( in t t i p o De E m i ss o r ) {
3 if ( t i p o D eE m i s so r = = E m i s s or C r e a to r . S M S ) {
www.k19.com.br 9
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 14/121
P ADRÕES DE CRIAÇÃO 10
4 r e t ur n n e w EmissorAssincronoSMS();
5 } e l s e i f ( t i p o D e Em i s s or = = E m i s so r C r ea t o r . E M A IL ) {
6 r e t ur n n e w EmissorAssincronoEmail();
7 } e l s e i f ( t i p o D e Em i s s or = = E m i s so r C r ea t o r . J M S ) {
8 r e t ur n n e w EmissorAssincronoJMS();
9 } else {1 t h r ow n e w IllegalArgumentException( " T i p o d e e m i ss o r n ã o s u p o r t ad o ") ;
11 }
12 }
13 }
Código Java 2.9: EmissorAssincronoCreator.java
1 p u b li c c l a ss EmissorSincronoCreator extends E m i s so r C r ea t o r {
2 public E m i ss o r c r e at e ( in t t i p o De E m i ss o r ) {
3 if ( t i p o D eE m i s so r = = E m i s s or C r e a to r . S M S ) {
4 r e t ur n n e w EmissorSincronoSMS();
5 } e l s e i f ( t i p o D e Em i s s or = = E m i s so r C r ea t o r . E M A IL ) {
6 r e t ur n n e w EmissorSincronoEmail();
7 } e l s e i f ( t i p o D e Em i s s or = = E m i s so r C r ea t o r . J M S ) {8 r e t ur n n e w EmissorSincronoJMS();
9 } else {
1 t h r ow n e w IllegalArgumentException( " T i p o d e e m i ss o r n ã o s u p o r t ad o ") ;
11 }
12 }
13 }
Código Java 2.10: EmissorSincronoCreator.java
Agora, para enviar uma mensagem, podemos acionar o criador adequado (EmissorCreator,EmissorAssincronoCreator ou EmissorSincronoCreator) para obter o emissor desejado.
1 E mi ss or Cr ea to r c r ea to r = ne w EmissorAssincronoCreator();
2 E m i ss o r e mi s s or = c r ea t o r . c r ea t e ( E m i s so r C r ea t o r . S MS )
3 e mi ss or . e nv ia (" K 1 9 - T r e i na m e n to s " );
Código Java 2.11: Enviando uma mensagem por SMS
1 E mi ss or Cr ea to r c r ea to r = ne w EmissorAssincronoCreator();
2 E m i ss o r e mi s s or = c r ea t o r . c r ea t e ( E m i s so r C r ea t o r . E M AI L )
3 e mi ss or . e nv ia (" K 1 9 - T r e i na m e n to s " );
Código Java 2.12: Enviando uma mensagem por email
1 E mi ss or Cr ea to r c r ea to r = ne w EmissorSincronoCreator();
2 E m i ss o r e mi s s or = c r ea t o r . c r ea t e ( E m i s so r C r ea t o r . J MS )
3 e mi ss or . e nv ia (" K 1 9 - T r e i na m e n to s " );
Código Java 2.13: Enviando uma mensagem por JMS
Organização
O diagrama UML abaixo ilustra a organização desse padrão.
10 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 15/121
11 P ADRÕES DE CRIAÇÃO
Figura 2.2: UML do padrão Factory Method
Os personagens desse padrão são:
Product (Emissor)Classe ou interface que define o objeto a ser criado.
ConcreteProduct (EmissorSMS)Uma implementação particular do tipo de objeto a ser criado.
Creator (EmissorCreator)Classe ou interface que define a assinatura do método responsável pela criação do produto.
Pode possuir uma implementação padrão do método de criação do produto.
ConcreteCreator (EmissorAssincronoCreator)Classe que implementa ou sobrescreve o método de criação do produto.
Exercícios de Fixação
1 Crie um projeto Java no Eclipse chamado FactoryMethod.
2 Defina uma interface Emissor.1 public interface E m i ss o r {
2 void envia(String mensagem);
3 }
Código Java 2.14: Emissor.java
3 Defina as classes EmissorSMS, EmissorEmail e EmissorJMS que irão implementar a interfaceEmissor.
1 p u b li c c l a ss EmissorSMS implements E m i ss o r {
2 p u b li c v o id e n v ia ( S t r i ng m e s sa g e ) {
3 System . out . println ( " E n vi a nd o p or S MS a m e ns a ge m : " );
4 System .out . println (message );5 }
6 }
www.k19.com.br 11
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 16/121
P ADRÕES DE CRIAÇÃO 12
Código Java 2.15: EmissorSMS.java
1 p u b li c c l a ss EmissorEmail implements E m i ss o r {
2 p u b li c v o id e n v ia ( S t r i ng m e s sa g e ) {
3 System . out . println ( " E n vi a nd o p or e ma i l a m e ns a ge m : ");
4 System .out . println (message );
5 }
6 }
Código Java 2.16: EmissorEmail.java
1 p u b li c c l a ss EmissorJMS implements E m i ss o r {
2 p u b li c v o id e n v ia ( S t r i ng m e s sa g e ) {
3 System . out . println ( " E n vi a nd o p or J MS a m e ns a ge m : " );
4 System .out . println (message );
5 }
6 }
Código Java 2.17: EmissorJMS.java
4 Crie uma classe para testar os emissores.
1 p u b li c c l a ss T e s t aE m i s so r e s {
2 p u b li c s t a ti c v o id m a i n ( S tr i n g [] a r gs ) {
3 Emissor emissor1 = ne w EmissorSMS();
4 emissor1 . envia ( " K 1 9 T r e i na m e n to s " );
5
6 Emissor emissor2 = ne w EmissorEmail();
7 emissor2 . envia ( " K 1 9 T r e i na m e n to s " );
8
9 Emissor emissor3 = ne w EmissorJMS();
1 emissor3 . envia ( " K 1 9 T r e i na m e n to s " );
11 }12 }
Código Java 2.18: TestaEmissores.java
5 Para tornar a classe TestaEmissores menos dependente das classes que implementam os me-canismos de envio, podemos definir uma classe intermediária que será responsável pela criação dosemissores.
1 p u b li c c l a ss E m i s so r C r ea t o r {
2 p u b li c s t a ti c f i n al i n t S MS = ;
3 p u b li c s t a ti c f i n al i n t E MA I L = 1 ;
4 p u b li c s t a ti c f i n al i n t J MS = 2 ;
5
6 public E m i ss o r c r e at e ( in t t i p o De E m i ss o r ) {
7 if ( t i p o D eE m i s so r = = E m i s s or C r e a to r . S M S ) {
8 r e t ur n n e w EmissorSMS();
9 } e l s e i f ( t i p o D e Em i s s or = = E m i s so r C r e at o r . E M A IL ) {
1 r e t ur n n e w EmissorEmail();
11 } e l s e i f ( t i p o D e Em i s s or = = E m i s so r C r e at o r . J M S ) {
12 r e t ur n n e w EmissorJMS();
13 } else {
14 t h r ow n e w IllegalArgumentException( " T i p o d e e m i ss o r n ã o s u p o r t ad o ") ;
15 }
16 }
17 }
Código Java 2.19: EmissorCreator.java
6 Altere a classe TestaEmissores para utilizar a classe EmissorCreator.
12 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 17/121
13 P ADRÕES DE CRIAÇÃO
1 p u b li c c l a ss T e s t aE m i s so r e s {
2 p u b li c s t a ti c v o id m a i n ( S tr i n g [] a r gs ) {
3 EmissorCreator creator = ne w EmissorCreator();
4
5 //SMS
6 E mi ss or e mi ss or 1 = c re at or . cr ea te ( Em is so rC re at or . SMS );7 emissor1 . envia ( " K 1 9 T r e i na m e n to s " );
8
9 //Email
1 E mi ss or e mi ss or 2 = c re at or . cr ea te ( Em is so rC re at or . EM AI L) ;
11 emissor2 . envia ( " K 1 9 T r e i na m e n to s " );
12
13 //JMS
14 E mi ss or e mi ss or 3 = c re at or . cr ea te ( Em is so rC re at or . JMS );
15 emissor3 . envia ( " K 1 9 T r e i na m e n to s " );
16 }
17 }
Código Java 2.20: TestaEmissores.java
Abstract Factory
Objetivo: Encapsular a escolha das classes concretas a serem utilizadas na criação dos objetos de
diversas famílias.
Exemplo prático
Estabelecimentos comerciais normalmenteoferecem aos clientes diversas opções de pagamento.Por exemplo, clientes podem efetuar pagamentos com dinheiro, cheque, cartões de crédito ou dé-bito, entre outros.
Pagamentos com cartões são realizados por meio de uma máquina de cartão, oferecida e insta-lada por empresas como Cielo e Redecard. Geralmente, essa máquina é capaz de lidar com cartõesde diferentes bandeiras (como Visa e Mastercard).
Nosso objetivo é programar essas máquinas, isto é, desenvolver uma aplicação capaz de se co-municar com as diferentes bandeiras e registrar pagamentos.
No momento do pagamento, a máquina de cartão deve enviar as informações relativas a transa-
ção (como valor e senha) para a bandeira correspondente ao cartão utilizado. Além disso, a máquinadeve aguardar uma resposta de confirmação ou recusa do pagamento.
www.k19.com.br 13
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 18/121
P ADRÕES DE CRIAÇÃO 14
Figura 2.3: Máquina de cartão interagindo com a bandeira
Na seção anterior, modelamos um sistema de envio de mensagens utilizando o padrão Factory Method. Para desenvolver a aplicação que executará nas máquinas de cartão, devemos implementar
algo semelhante que, além de enviar mensagens, também precisa receber.
O nosso sistema será composto por objetos emissores e receptores de mensagens. Como o pro-tocolo de comunicação de cada bandeira é diferente. Como cada bandeira possui o seu próprioprotocolo de comunicação, teremos um emissor e um receptor para cada bandeira.
Criaremos fábricas específicas para cada bandeira. Essas fábricas serão responsáveis pela criaçãodos emissores e receptores. Para padronizá-las, podemos criar uma interface.
1 public interface C o m u n ic a d o r Fa c t o ry {
2 Em iss or c re at eE mi sso r() ;
3 Re ce pt or c rea te Re ce pt or () ;
4 }
Código Java 2.21: ComunicadorFactory.java
14 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 19/121
15 P ADRÕES DE CRIAÇÃO
1 p u b li c c l a ss VisaComunicadorFactory implements C o m u ni c a d o rF a c t o ry {
2 public E m i ss o r c r e a te E m i ss o r ( ) {
3 / / c r ia n do u m e m is s or V is a
4 }
56 public R e c ep t o r c r e a te R e c ep t o r ( ) {
7 / / c r ia n do u m r e ce p to r V is a
8 }
9 }
Código Java 2.22: VisaComunicadorFactory.java
1 p u b li c c l a ss MastercardComunicadorFactory implements C o m u n ic a d o rF a c t o ry {
2 public E m i ss o r c r e a te E m i ss o r ( ) {
3 / / c r i an d o u m e m i ss o r M a s te r c a rd
4 }
5
6 public R e c ep t o r c r e a te R e c ep t o r ( ) {
7 / / c r i an d o u m r e c ep t o r M a s t er c a r d
8 }
9 }
Código Java 2.23: MastercardComunicadorFactory.java
O processo de escolha da fábrica é realizado de acordo com a bandeira do cartão utilizado.
1 public C o m u ni c a d o rF a c t or y g e t C o mu n i c a do r F a ct o r y ( C a r ta o c a r ta o ) {
2 S tr in g b an de ir a = c ar ta o. ge tB an de ir a () ;
3 C la ss c la zz = C la ss . fo rN am e( b an de ir a + "ComunicadorFactory" );
4 return (ComunicadorFactory) clazz.newInstance();
5 }
Código Java 2.24: Selecionando a fábrica de acordo com as preferências do usuário
Dessa forma, o código da aplicação se torna independente da fábrica utiliza.
1 C ar ta o c ar ta o = .. .
2 C o m u n ic a d o rF a c t o ry f a c t or y = g e t C om u n i ca d o r F ac t o r y ( c a rt a o ) ;
3
4 S tr in g t ra ns ac ao = . ..
5 E m is s or e m is s or = f a ct o ry . g e tE m is s or ( ) ;
6 e m is s or . e n vi a ( t ra n sa c ao ) ;
7
8 R e ce p to r r e ce p to r = f a ct o ry . g e t Re c ep t or ( ) ;9 S tr i ng r e s p os t a = r e ce p to r . r ec e be ( ) ;
Código Java 2.25: enviando mensagens
Organização
O diagrama UML abaixo ilustra a organização desse padrão.
www.k19.com.br 15
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 20/121
P ADRÕES DE CRIAÇÃO 16
Figura 2.4: UML do padrão Abstract Factory
Os personagens desse padrão são:
AbstractFactory (ComunicadorFactory)Interface que define as assinaturas dos métodos responsáveis pela criação dos objetos umafamília.
ConcreteFactory (VisaComunicadorFactory , MastercardComunicadorFactory )Classe que implementa os métodos de criação dos objetos de uma família.
AbstractProduct (Emissor, Receptor)Interface que define um tipo de produto.
ConcreteProduct (EmissorVisa, ReceptorVisa, EmissorMastercard, ReceptorMastercard)Implementação particular de um tipo de produto.
Client (Aplicação)Usa apenas as interfaces AbstractFactory e AbstractProduct.
Abstract Factory + Factory Method
Podemos combinar os dois padrões vistos anteriormente. As implementações da Abstract Fac-tory podem acionar os Factory Methods para criar os emissores e receptores.
1 p u b li c c l a ss VisaComunicadorFactory implements C o m u ni c a d o rF a c t o ry {
2 private E m i s so r C r ea t o r e m i s so r C r ea t o r = ne w EmissorCreator();
3 private R e c e pt o r C re a t o r r e c e p to r C r ea t o r = ne w ReceptorCreator();
4
5 public E m i ss o r c r e a te E m i ss o r ( ) {
6 r e t ur n t h is .emissorCreator.create(EmissorCreator.VISA);
7 }
8
9 public R e c ep t o r c r e a te R e c ep t o r ( ) {1 r e t ur n t h is .receptorCreator.create(ReceptorCreator.VISA);
11 }
16 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 21/121
17 P ADRÕES DE CRIAÇÃO
12 }
Código Java 2.26: VisaComunicadorFactory.java
1 p u b li c c l a ss MastercardComunicadorFactory implements C o m u n ic a d o rF a c t o ry {2 private E m i s so r C r ea t o r e m i s so r C r ea t o r = ne w EmissorCreator();
3 private R e c e pt o r C re a t o r r e c e p to r C r ea t o r = ne w ReceptorCreator();
4
5 public E m i ss o r c r e a te E m i ss o r ( ) {
6 r e t ur n t h is .emissorCreator.create(EmissorCreator.MASTERCARD);
7 }
8
9 public R e c ep t o r c r e a te R e c ep t o r ( ) {
1 r e t ur n t h is .receptorCreator.create(ReceptorCreator.MASTERCARD);
11 }
12 }
Código Java 2.27: MastercardComunicadorFactory.java
Exercícios de Fixação
7 Crie um projeto chamado AbstractFactory .
8 Defina as interfaces Receptor e Emissor.
1 public interface E m i ss o r {
2 void envia(String mensagem);
3 }
Código Java 2.28: Emissor.java
1 public interface R e c ep t o r {
2 String recebe () ;
3 }
Código Java 2.29: Receptor.java
9 Defina as implementações Visa e Mastercard para as interfaces Emissor e Receptor.
1 p u b li c c l a ss ReceptorVisa implements R e c ep t o r {
2 p u b li c v o id r e c eb e ( S t r in g m e n sa g e m ) {
3 System . out . println ( " R e c e be n d o m e n s ag e m d a V i sa . ");
4 String mensagem = " M e n s a ge m d a V i s a ";
5 return mensagem;
6 }
7 }
Código Java 2.30: ReceptorVisa.java
1 p u b li c c l a ss ReceptorMastercard implements R e c ep t o r {
2 public S t r in g r e c eb e ( ) {
3 System . out . println ( " R e c e be n d o m e n s ag e m d a M a s t er c a rd . " );
4 String mensagem = " M e n s a ge m d a M a s t er c a r d ";
5 return mensagem;
6 }
7 }
Código Java 2.31: ReceptorMastercard.java
1 p u b li c c l a ss EmissorVisa implements E m i ss o r {2 p u b li c v o id e n v ia ( S t r i ng m e n s ag e m ) {
3 System . out . println ( " E n vi a nd o a s e gu i nt e m e ns a ge m p ar a a V is a : ") ;
www.k19.com.br 17
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 22/121
P ADRÕES DE CRIAÇÃO 18
4 System .out .println (mensagem );
5 }
6 }
Código Java 2.32: EmissorVisa.java
1 p u b li c c l a ss EmissorMastercard implements E m i ss o r {
2 p u b li c v o id e n v ia ( S t r i ng m e n s ag e m ) {
3 System . out . println ( " E n v i an d o a s e g ui n t e m e n sa g e m p a r a a M a s te r c a rd : " );
4 System .out .println (mensagem );
5 }
6 }
Código Java 2.33: EmissorMastercard
10 Defina as fábricas de emissores e receptores.
1 p u b li c c l a ss E m i s so r C r ea t o r {
2 p u b li c s t a ti c f i n al i n t V IS A = ;
3 p u b li c s t a ti c f i n al i n t M A ST E RC A RD = 1 ;
4
5 public E m i ss o r c r e at e ( in t t i p o Do E m i ss o r ) {
6 if ( t i p o D oE m i s so r = = E m i s s or C r e a to r . V I S A ) {
7 r e t ur n n e w EmissorVisa();
8 } e l s e i f ( t i p o D o Em i s s or = = E m i s so r C r ea t o r . M A S T ER C A RD ) {
9 r e t ur n n e w EmissorMastercard();
1 } else {
11 t h r ow n e w IllegalArgumentException( " T i p o d e e m i ss o r n ã o s u p o r t ad o ") ;
12 }
13 }
14 }
Código Java 2.34: EmissorCreator.java
1 p u b li c c l a ss R e c e pt o r C re a t o r {
2 p u b li c s t a ti c f i n al i n t V IS A = ;
3 p u b li c s t a ti c f i n al i n t M A ST E RC A RD = 1 ;
4
5 public R e c ep t o r c r e at e ( in t t i p o Do R e c ep t o r ) {
6 if ( t i p o D oR e c e p to r = = R e c e pt o r C re a t o r . V I SA ) {
7 r e t ur n n e w ReceptorVisa();
8 } e l s e i f ( t i p o D o Re c e p to r = = R e c e pt o r C re a t o r . M A S TE R C A RD ) {
9 r e t ur n n e w ReceptorMastercard();
1 } else {
11 t h r ow n e w IllegalArgumentException( " T i p o d e r e c ep t o r n ã o s u p or t a d o . ");
12 }
13 }
14 }
Código Java 2.35: ReceptorCreator.java
11 Crie uma interface ComunicadorFactory para padronizar as fábricas de emissores e receptores.
1 public interface C o m u n ic a d o r Fa c t o ry {
2 Em iss or c re at eE mi sso r() ;
3 Re ce pt or c rea te Re ce pt or () ;
4 }
Código Java 2.36: ComunicadorFactory.java
12 Crie uma fábrica de emissores e receptores Visa.
1 p u b li c c l a ss VisaComunicadorFactory implements C o m u ni c a d o rF a c t o ry {2 private E m i s so r C r ea t o r e m i s so r C r ea t o r = ne w EmissorCreator();
3 private R e c e pt o r C re a t o r r e c e p to r C r ea t o r = ne w ReceptorCreator();
18 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 23/121
19 P ADRÕES DE CRIAÇÃO
4
5 public E m i ss o r c r e a te E m i ss o r ( ) {
6 return emissorCreator.create(EmissorCreator.VISA);
7 }
8
9 public R e c ep t o r c r e a te R e c ep t o r ( ) {1 return receptorCreator.create(ReceptorCreator.VISA);
11 }
12 }
Código Java 2.37: VisaComunicadorFactory.java
13 Crie uma fábrica de emissores e receptores Mastercard.
1 p u b li c c l a ss MastercardComunicadorFactory implements C o m u n ic a d o rF a c t o ry {
2 private E m i s so r C r ea t o r e m i s so r C r ea t o r = ne w EmissorCreator();
3 private R e c e pt o r C re a t o r r e c e p to r C r ea t o r = ne w ReceptorCreator();
4
5 public E m i ss o r c r e a te E m i ss o r ( ) {
6 return emissorCreator.create(EmissorCreator.MASTERCARD);
7 }
8
9 public R e c ep t o r c r e a te R e c ep t o r ( ) {
1 return receptorCreator.create(ReceptorCreator.MASTERCARD);
11 }
12 }
Código Java 2.38: MastercardComunicadorFactory.java
14 Faça uma classe para testar a fábrica de emissores e receptores Visa.
1 p u b li c c l a ss TestaVisaComunicadorFactory {
2 p u b li c s t a ti c v o id m a i n ( S tr i n g [] a r gs ) {3 C om uni ca do rF ac to ry c om un ic ad or Fa ct or y = ne w VisaComunicadorFactory();
4
5 String transacao = "Valor=56;Senha=123" ;
6 E mi ss or e mi ss or = c om un ic ad or Fa ct or y. c re at eE mi ss or () ;
7 emissor .envia (transacao );
8
9 R ec ep to r r ec ep to r = c om un ic ad or Fa ct or y .c re at eR ec ep to r () ;
1 String mensagem = receptor .recebe () ;
11 System .out .println (mensagem );
12 }
13 }
Código Java 2.39: TestaVisaComunicadorFactory.java
Exercícios Complementares
1 Faça uma classe para testar a fábrica de emissores e receptores da Mastercard.
Builder
Objetivo: Separar o processo de construção de um objeto de sua representação e permitir a sua
criação passo-a-passo. Diferentes tipos de objetos podem ser criados com implementações distintas de
cada passo.
www.k19.com.br 19
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 24/121
P ADRÕES DE CRIAÇÃO 20
Exemplo prático
Estamos desenvolvendo um sistema para gerar boletos bancários. No Brasil, a FEBRABAN (Fede-ração Brasileira de Bancos) define regras gerais para os boletos. Contudo, cada instituição bancáriadefine também as suas próprias regras específicas para o formato dos dados dos boletos.
Segundo a FEBRABAN, os elementos principais relacionados a um boleto são:
Sacado: Pessoa ou empresa responsável pelo pagamento do boleto.
Cedente: Pessoa ou empresa que receberá o pagamento do boleto.
Banco: Instituição que receberá o pagamento do sacado e creditará o valor na conta do cedente.
Código de Barras: Representação gráfica das informações do boleto.
Linha Digitável: Representação numérica das informações do boleto.
Nosso Número: Código de identificação do boleto utilizado pela instituição bancária e pelo cedentepara controle dos pagamentos.
20 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 25/121
21 P ADRÕES DE CRIAÇÃO
Cedente
Sacado
Nosso Número
Valor
Vencimento
Cedente
Sacado
Nosso Número
Valor
Vencimento
K19 Treinamentos
Rafael Cosentino
Cedente
Sacado
Nosso Número
Valor
Vencimento
K19 Treinamentos1234567890
R$ 300,00
12/12/2012Rafael Cosentino
K19 Bank
Cedente
Sacado
Nosso Número
Valor
Vencimento
|252-0| 857-09543-234-12464278-27857-5487362-34613-35
K19 Treinamentos1234567890
R$ 300,00
12/12/2012Rafael Cosentino
Figura 2.5: Passo-a-passo da criação de um boleto
Para gerar um boleto, devemos definir todas essas informações. Para encapsular a complexidadedesse processo, poderíamos definir classes responsáveis pela criação dos boletos de acordo com ainstituição bancária. Inclusive, poderíamos padronizar essas classes através de uma interface.
1 public i n t e fa c e B o l e to B u i ld e r {
2 void buildSacado(String sacado);
3 void buildCedente(String cedente);
4 void buildValor( double valor);5 void buildVencimento(Calendar vencimento);
6 void buildNossoNumero( in t nossoNumero);
www.k19.com.br 21
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 26/121
P ADRÕES DE CRIAÇÃO 22
7 void buildCodigoDeBarras();
8 void buildLogotipo();
9
1 Boleto getBoleto () ;
11 }
Código Java 2.40: BoletoBuilder.java
1 p u b li c c l a ss BBBoletoBuilder implements B o l e to B u i ld e r {
2 / / i m pl e me n ta ç ão d os m é to d os s e gu i nd o a s r e gr a s d a F E BR A BA N e d o B B
3 }
Código Java 2.41: BBBoletoBuilder.java
1 p u b li c c l a ss ItauBoletoBuilder implements B o l e to B u i ld e r {
2 / / i m pl e me n ta ç ão d os m é to d os s e gu i nd o a s r e gr a s d a F E BR A BA N e d o I ta ú
3 }
Código Java 2.42: ItauBoletoBuilder.java
1 p u b li c c l a ss BradescoBoletoBuilder implements B o l e to B u i ld e r {
2 / / i m pl e me n ta ç ão d os m é to d os s e gu i nd o a s r e gr a s d a F E BR A BA N e d o B r ad e sc o
3 }
Código Java 2.43: BradescoBoletoBuilder.java
Agora, poderíamos obter de alguma fonte externa (usuário, banco de dados, arquivos e etc) asinformações necessárias e gerar um boleto utilizando o montador adequado.
1 p u b li c c l a ss G e r a do r D e Bo l e t o {
2 private BoletoBuilder boletoBuilder;
3
4 public G e r a do r D e Bo l e t o ( B o l et o B u il d e r b o l e to B u i ld e r ) {5 this . b o l e t o Bu i l d er = b o l e to B u i ld e r ;
6 }
7
8 public B o l et o g e r a Bo l e t o ( ) {
9 String sacado = ...
1 this .boletoBuilder.buildSacado(sacado);
11
12 String cedente = ...
13 this .boletoBuilder.buildCedente(cedente);
14
15 double v al o r = . ..
16 this .boletoBuilder.buildValor(valor);
17
18 Calendar vencimento = ...
19 this .boletoBuilder.buildVencimento(vencimento);
221 this .boletoBuilder.buildCodigoDeBarras();
22
23 this .boletoBuilder.buildLogotipo();
24
25 r e t ur n t h is .boletoBuilder.getBoleto();
26 }
27 }
Código Java 2.44: GeradorDeBoleto.java
Quando for necessário gerar um boleto, devemos escolher uma implementação da interfaceBoletoBuilder.
1 B o le t oB u il d er b o l et o Bu i ld e r = ne w BBBoletoBuilder();2 G e ra d or D eB o le t o g e ra d or D eB o le t o = ne w GeradorDeBoleto(boletoBuilder);
3 B ol e to b o le t o = g e ra d or D eB o le t o . g er a Bo l et o ( );
22 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 27/121
23 P ADRÕES DE CRIAÇÃO
Código Java 2.45: Gerando um boleto
Organização
O diagrama UML abaixo ilustra a organização desse padrão.
Figura 2.6: UML do padrão Builder
Os personagens desse padrão são:
Product (Boleto)Define os objetos que devem ser construídos pelos Builders.
Builder (BoletoBuilder)Interface que define os passos para a criação de um produto.
ConcreteBuilder (BBBoletoBuilder, ItauBoletoBuilder, BradescoBoletoBuilder)Constrói um produto específico implementando a interface Builder.
Director (GeradorDeBoleto) Aciona os método de um Builder para construir um produto.
Exercícios de Fixação
15 Crie um projeto chamado Builder.
16 Defina uma interface para os boletos.
1 public interface B o l et o {
2 String getSacado () ;
3 String getCedente () ;
4 double getValor();
5 Ca le nd ar g etV en cim en to () ;
6 in t getNossoNumero();7 String toString () ;
8 }
www.k19.com.br 23
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 28/121
P ADRÕES DE CRIAÇÃO 24
Código Java 2.46: Boleto.java
17 Defina a classe BBBoleto que implementa a interface Boleto.
1 p u b li c c l a ss BBBoleto implements B o l et o {
2 private S t r in g s a c ad o ;
3 private S t r in g c e d en t e ;
4 p r i va t e d o u bl e valor;
5 private C a l e nd a r v e n ci m e n to ;
6 p r i va t e i n t nossoNumero;
7
8 public BBBoleto(String sacado , String cedente , double valor , Calendar vencimento , ←
in t n o s s oN u m e ro ) {
9 this . s a c a do = s a c ad o ;
1 this . c e d e nt e = c e d en t e ;
11 this . v a lo r = v a lo r ;
12 this . v e n c i me n t o = v e n c im e n t o ;
13 this . n o s s o Nu m e r o = n o s s oN u m e ro ;14 }
15
16 public S t r in g g e t Sa c a d o ( ) {
17 r e t ur n t h is .sacado;
18 }
19
2 public S t r in g g e t C ed e n t e ( ) {
21 r e t ur n t h is .cedente;
22 }
23
24 p u b li c d o u bl e g e t Va l o r ( ) {
25 r e t ur n t h is .valor;
26 }
27
28 public C a l en d a r g e t V en c i m en t o ( ) {
29 r e t ur n t h is .vencimento;
3 }
31
32 p u b li c i n t g e t N o ss o N u m er o ( ) {
33 r e t ur n t h is .nossoNumero;
34 }
35
36 public S t r in g t o S tr i n g ( ) {
37 StringBuilder stringBuilder = ne w StringBuilder();
38 stringBuilder .append (" B o l e to B B ");
39 stringBuilder .append ("\n" );
4
41 stringBuilder .append (" S a ca do : " + this .sacado);
42 stringBuilder .append ("\n" );
43
44 stringBuilder .append (" C e d e nt e : " + this .cedente);45 stringBuilder .append ("\n" );
46
47 stringBuilder .append (" V a lo r : " + this .valor);
48 stringBuilder .append ("\n" );
49
5 stringBuilder .append (" V e n c i me n t o : " + this .sacado);
51 stringBuilder .append ("\n" );
52
53 SimpleDateFormat simpleDateFormat = ne w SimpleDateFormat( "dd/MM/yyyy" );
54 S tri ng fo rma t = si mp le Da te Fo rm at . fo rma t( this .vencimento.getTime());
55 stringBuilder .append (" V e n c i me n t o : " + f o rm a t );
56 stringBuilder .append ("\n" );
57
58 stringBuilder .append (" N o ss o N ú me r o : " + this .nossoNumero);
59 stringBuilder .append ("\n" );
661 return stringBuilder.toString();
62 }
24 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 29/121
25 P ADRÕES DE CRIAÇÃO
63 }
Código Java 2.47: Boleto.java
18 Defina uma interface que irá padronizar as classes responsáveis pela criação dos boletos.
1 public interface B o l e to B u i ld e r {
2 void buildSacado(String sacado);
3 void buildCedente(String cedente);
4 void buildValor( double valor);
5 void buildVencimento(Calendar vencimento);
6 void buildNossoNumero( in t nossoNumero);
7
8 Boleto getBoleto () ;
9 }
Código Java 2.48: BoletoBuilder.java
19 Defina uma classe responsável pela criação de boletos do banco BB.1 p u b li c c l a ss BBBoletoBuilder implements B o l e to B u i ld e r {
2 private S t r in g s a c ad o ;
3 private S t r in g c e d en t e ;
4 p r i va t e d o u bl e valor;
5 private C a l e nd a r v e n ci m e n to ;
6 p r i va t e i n t nossoNumero;
7
8 p u b li c v o id b u i ld S a c ad o ( S t r i ng s a c ad o ) {
9 this . s a c a do = s a c ad o ;
1 }
11
12 p u b li c v o id b u i l dC e d e nt e ( S t r i ng c e d en t e ) {
13 this . c e d e nt e = c e d en t e ;
14 }
1516 p u b li c v o id buildValor( double v a lo r ) {
17 this . v a lo r = v a lo r ;
18 }
19
2 p u b li c v o id b u i l dV e n c im e n t o ( C a l en d a r v e n c im e n to ) {
21 this . v e n c i me n t o = v e n c im e n t o ;
22 }
23
24 p u b li c v o id buildNossoNumero( in t n o s s oN u m e ro ) {
25 this . n o s s o Nu m e r o = n o s s oN u m e ro ;
26 }
27
28 public B o l et o g e t Bo l e t o ( ) {
29 r e t ur n n e w BBBoleto(sacado , cedente , valor , vencimento , nossoNumero);
3 }
31 }
Código Java 2.49: BBBoletoBuilder.java
20 Faça uma classe para gerar boletos.
1 p u b li c c l a ss G e r a do r D e Bo l e t o {
2 private BoletoBuilder boletoBuilder;
3
4 public G e r a do r D e Bo l e t o ( B o l et o B u il d e r b o l e to B u i ld e r ) {
5 this . b o l e t o Bu i l d er = b o l e to B u i ld e r ;
6 }
7
8 public B o l et o g e r a Bo l e t o ( ) {
91 this .boletoBuilder.buildSacado( " M a r c el o M a r ti n s ");
11
www.k19.com.br 25
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 30/121
P ADRÕES DE CRIAÇÃO 26
12 this .boletoBuilder.buildCedente( " K 1 9 T r e i na m e n to s " );
13
14 this .boletoBuilder.buildValor(1.54);
15
16 Ca le nd ar ve nci men to = Ca le nd ar . get Ins ta nc e() ;
17 vencimento .add (Calendar .DATE , 3) ;18 this .boletoBuilder.buildVencimento(vencimento);
19
2 this .boletoBuilder.buildNossoNumero(1234);
21
22 B ole to bo let o = b ol eto Bu ild er . ge tB ole to () ;
23
24 return boleto;
25 }
26 }
Código Java 2.50: GeradorDeBoleto.java
21 Faça uma classe para testar o gerador de boleto.
1 p u b li c c l a ss T e s t a Ge r a d or D e B o le t o {
2 p u b li c s t a ti c v o id m a i n ( S tr i n g [] a r gs ) {
3 BoletoBuilder boletoBuilder = ne w BBBoletoBuilder();
4 GeradorDeBoleto geradorDeBoleto = ne w GeradorDeBoleto(boletoBuilder);
5 B ole to bo let o = ge ra do rD eB ol et o. ger aBo let o() ;
6 System .out . println (boleto );
7 }
8 }
Código Java 2.51: TestaGeradorDeBoleto.java
Prototype
Objetivo: Possibilitar a criação de novos objetos a partir da cópia de objetos existentes.
Exemplo prático
Estamos desenvolvendo um sistema de anúncios semelhante ao do Google Adwords. Nesse sis-tema, os usuários poderão criar campanhas e configurá-las de acordo com as suas necessidades.
Uma campanha é composta por diversas informações, entre elas:
• Uma lista de anúncios.
• O valor diário máximo que deve ser gasto pela campanha.
• O valor máximo por exibição de anúncio.
• As datas de início e término.
Nesse tipo de sistema, os usuários geralmente criam campanhas com configurações extrema-mente parecidas. Dessa forma, seria interessante que o sistema tivesse a capacidade de criar uma
campanha a partir de uma outra campanha já criada anteriormente, para que as configurações pu-dessem ser aproveitadas.
26 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 31/121
27 P ADRÕES DE CRIAÇÃO
Treinamentos de Java e .NET
www.k19.com.br
Prepare-se para o mercado de trabalho
com os treinamentos da K19
Campanha Anual
K19 - Padrões de Projeto
www.k19.com.br
Novo treinamento de padrões de
projeto da K19
Campanha de Verão
Figura 2.7: Criando um anúncio a partir de um pré-existente
1 C
a m p an h a n o va = v e l ha . c r i a U m aC o p i a ( ) ;
Código Java 2.52: Criando uma campanha como cópia de outra
Vários objetos do nosso sistema poderiam ter essa capacidade. Seria interessante definir umainterface para padronizar e marcar os objetos com essas características.
1 public interface Prototype <T> {
2 T clone () ;
3 }
Código Java 2.53: Prototype.java
Depois, devemos implementar a interface Prototype nas classes que devem possuir a caracte-rística que desejamos.
1 p u b li c c l a ss Campanha implements Prototype <Campanha > {
2 / / a t ri b ut o s e m é to d os
3
4 public C a m pa n h a c l o ne ( ) {
5 / / l ó gi c a p ar a c ri a r u ma c óp i a d a c a mp a nh a t hi s
6 }
7 }
Código Java 2.54: Campanha.java
Quando o usuário quiser criar uma campanha com as mesmas configurações de uma campanha já criada, devemos escrever um código semelhante a este:
1 C am pa nh a c am pa nh a1 = . ..
2 C a mp a nh a c a m pa n ha 2 = c a mp a nh a 1 . cl on e ( );
3 c a mp a nh a 2 . se t No m e (" K 19 - C a mp a nh a d e V er ã o ");
4 c a m pa n h a 2 . g e tA n u n ci o s ( ) . g et ( ) . s e t Ti t u l o (" K 19 - P a dr õ es d e P r oj e to " );
5 c a m pa n h a 2 . g e tA n u n ci o s ( ) . g et ( ) . s e t Te x t o (" N ov o t r ei n am e nt o d e P a dr õ es d e P r oj e to d a K 19←
" );
Código Java 2.55: clonando uma campanha
www.k19.com.br 27
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 32/121
P ADRÕES DE CRIAÇÃO 28
Organização
Figura 2.8: UML do padrão Prototype
Os personagens desse padrão são:
Prototype Abstração dos objetos que possuem a capacidade de se auto copiar.
ConcretePrototype (Campanha)Classe que define um tipo particular de objeto que pode ser clonado.
ClientClasse que cria novos objetos a partir da interface definida por Prototype.
Exercícios de Fixação
22 Crie um projeto Java chamado Prototype.
23 Defina uma interface Prototype.
1 public interface Prototype <T> {
2 T clone () ;
3 }
Código Java 2.56: Prototype.java
24 Defina uma classe Campanha que implementa a interface Prototype.
1 p u b li c c l a ss Campanha implements Prototype <Campanha > {
2 private S t r in g n o me ;
3 private C a l e nd a r v e n ci m e n to ;
4 private Set<String > palavrasChave;
5
6 public C a m pa n h a ( S t ri n g n om e , C a l e nd a r v e n ci m e nt o , S et < S t r i ng > p a l a vr a s C ha v e ) {
7 this . n om e = n om e ;
8 this . v e n c i me n t o = v e n c im e n t o ;
9 this . p a l a v r as C h a ve = p a l a vr a s C ha v e ;
1 }
11
12 public S t r in g g e t No m e ( ) {13 return nome;
14 }
28 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 33/121
29 P ADRÕES DE CRIAÇÃO
15
16 public C a l en d a r g e t V en c i m en t o ( ) {
17 return vencimento;
18 }
19
2 public Set<String > getPalavrasChave() {21 return palavrasChave;
22 }
23
24 public C a m pa n h a c l o ne ( ) {
25 String nome = " C ó pi a d a C a mp a nh a : " + this .nome;
26 Calendar vencimento = ( Calendar ) this .vencimento.clone();
27 Set <String > palavrasChave = ne w HashSet <String >( this .palavrasChave);
28 Campanha campanha = ne w Campanha(nome, vencimento , palavrasChave);
29
3 return campanha;
31 }
32
33 public S t r in g t o S tr i n g ( ) {
34 StringBuffer buffer = ne w StringBuffer();
35 buffer . append ("---------------" ) ;
36 buffer . append ("\n" ) ;
37 buffer . append (" N o me d a C a mp a nh a : ");
38 buffer . append ( this .nome);
39 buffer . append ("\n" ) ;
4
41 SimpleDateFormat simpleDateFormat = ne w SimpleDateFormat( "dd/MM/yyyy" );
42 S tri ng fo rma t = si mp le Da te Fo rm at . fo rma t( this .vencimento.getTime());
43 buffer . append (" V e n c i me n t o : " + f o r ma t ) ;
44 buffer . append ("\n" ) ;
45
46 buffer . append ("Palavras -chave: \n" );
47 fo r ( S t r i ng p a l a vr a C h av e : this . p a l a v r as C h a ve ) {
48 buffer . append (" - " + p a l a vr a C h av e ) ;
49 buffer . append ("\n" );
5 }
51 buffer . append ("---------------" ) ;52 buffer . append ("\n" ) ;
53
54 return buffer.toString();
55 }
56 }
Código Java 2.57: Campanha.java
25 Faça uma classe para testar o método clone.
1 p u b li c c l a ss T e s t aP r o t ot y p e {
2 p u b li c s t a ti c v o id m a i n ( S tr i n g [] a r gs ) {
3 String nome = "K19" ;
4
5 Ca le nd ar ve nci men to = Ca le nd ar . get Ins ta nc e() ;6 vencimento .add (Calendar .DATE , 3) ;
7
8 Set <String > hashSet = ne w HashSet <String >();
9
1 hashSet . add ("curso" );
11 hashSet . add ("java" ) ;
12 hashSet . add ("k19" );
13
14 Campanha campanha = ne w Campanha(nome, vencimento , hashSet);
15 System .out .println (campanha );
16
17 Campanha clone = campanha .clone () ;
18 System .out . println (clone );
19 }
2 }
Código Java 2.58: TestaPrototype.java
www.k19.com.br 29
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 34/121
P ADRÕES DE CRIAÇÃO 30
Singleton
Objetivo: Permitir a criação de uma única instância de uma classe e fornecer um modo para recuperá-la.
Exemplo prático
Suponha que estamos desenvolvendo um sistema que possui configurações globais obtidas apartir de um arquivo de propriedades. Essas configurações podem ser armazenadas em um objeto.
1 p u b li c c l a ss C o n f ig u r a ca o {
2 private Map<String , String > propriedades = ne w HashMap <String ,String >();
3
4 public C o n f ig u r a ca o ( ) {
5 / / c a r re g a a s p r o p ri e d a de s o b t id a s d o a r q ui v o d e c o n f ig u r a ca o
6 }
7
8 public S t r in g g e t P ro p r i ed a d e ( S t r in g n o m e D aP r o p ri e d a d e ) {
9 r e t ur n t h is .propriedades.get(nomeDaPropriedade);
1 }
11 }
Código Java 2.59: Configuracao.java
Não desejamos que existam mais do que um objeto dessa classe ao mesmo tempo no sistema.Para garantir essa restrição, podemos tornar o construtor da classe Configuracao privado e imple-
mentar um método estático que controle a criação do único objeto que deve existir.1 p u b li c c l a ss C o n f ig u r a ca o {
2 p r i va t e s t a ti c C o n f ig u r a ca o i n s ta n c e ;
3
4 private Map<String , String > propriedades = ne w HashMap <String ,String >();
5
6 private C o n f ig u r a ca o ( ) {
7 / / c a r re g a a s p r o p ri e d a de s o b t id a s d o a r q ui v o d e c o n f ig u r a ca o
8 }
9
1 p u b li c s t a ti c C o n f ig u r a ca o g e t I ns t a n ce ( ) {
11 if ( C o n f i gu r a c ao . i n s t a n ce = = null ) {
12 Configuracao . instance = ne w Configuracao();
13 }
14 return Configuracao.instance;
15 }
16
17 public S t r in g g e t P ro p r i ed a d e ( S t r in g n o m e D aP r o p ri e d a d e ) {
18 r e t ur n t h is .propriedades.get(nomeDaPropriedade);
19 }
2 }
Código Java 2.60: Configuracao.java
De qualquer ponto do código do nosso sistema, podemos acessar o objeto que contém as confi-gurações da aplicação.
1 S t r in g t i m e Zo n e = C o nf i g u ra c a o . g e t I ns t a n ce ( ) . g e t P r o pr i e d ad e ( "time-zone" );
Código Java 2.61: acessando as propriedades
30 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 35/121
31 P ADRÕES DE CRIAÇÃO
Organização
O diagrama UML abaixo ilustra a organização desse padrão.
Figura 2.9: UML do padrão Singleton
O personagem desse padrão é:
Singleton (Configuracao)Classequepermiteacriaçãodeumaúnicainstânciaeforneceummétodoestáticopararecuperá-
la.
Exercícios de Fixação
26 Crie um projeto Java chamado Singleton.
27 Crie a classe Configuração e impeça que mais de um objeto exista ao mesmo tempo no sistema.
1 p u b li c c l a ss C o n f ig u r a ca o {
2 private Map<String , String > propriedades;
3 p r i va t e s t a ti c C o n f ig u r a ca o i n s ta n c e ;4
5 private C o n f ig u r a ca o ( ) {
6 this . p r o p r ie d a d es = ne w HashMap <String , String >();
7 this .propriedades.put( "time-zone" , "America/Sao_Paulo" );
8 this .propriedades.put( "currency -code" , "BRL" ) ;
9 }
1
11 p u b li c s t a ti c C o n f ig u r a ca o g e t I ns t a n ce ( ) {
12 if ( C o n f i gu r a c ao . i n s t a n ce = = null ) {
13 Configuracao . instance = ne w Configuracao();
14 }
15 return Configuracao.instance;
16 }
17
18 public S t r in g g e t P ro p r i ed a d e ( S t r in g n o m e D aP r o p ri e d a d e ) {
19 r e t ur n t h is .propriedades.get(nomeDaPropriedade);2 }
21 }
Código Java 2.62: Configuracao.java
28 Teste a classe Configuracao.
1 p u b li c c l a ss T e s t aS i n g le t o n {
2 p u b li c s t a ti c v o id m a i n ( S tr i n g [] a r gs ) {
3 C on fi gu ra ca o c on fi gu ra ca o = C on fi gu ra ca o. g et In st an ce () ;
4 S ys te m. ou t. pr in tl n( c on fi gu ra ca o. g et Pr op ri ed ad e ("time-zone" )) ;
5 S ys te m. ou t. pr in tl n( c on fi gu ra ca o. g et Pr op ri ed ad e ("currency -code") );
6 }
7 }
Código Java 2.63: TestaSingleton.java
www.k19.com.br 31
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 36/121
P ADRÕES DE CRIAÇÃO 32
Multiton (não GoF)
Objetivo: Permitir a criação de uma quantidade limitada de instâncias de determinada classe e fornecer um modo para recuperá-las.
Exemplo prático
Estamos desenvolvendo uma aplicação que possuirá diversos temas para interface do usuário. Onúmero de temas é limitado e cada usuário poderá escolher o de sua preferência. Podemos imple-mentar os temas através de uma classe.
1 p u b li c c l a ss T em a {
2 private S t r in g n o me ;
3 private C o l or c o r D oF u n d o ;4 private C o l or c o r D aF o n t e ;
5
6 / / G E T TE R S A N D S E T T E R S
7 }
Código Java 2.64: Tema.java
Agora, devemos criar os temas que serão disponibilizados para a escolha dos usuários.
1 Tema tema1 = ne w Tema();
2 t em a1 . s et No me ("Sky" );
3 t e m a1 . s e t C o r D oF u n d o ( C ol o r . B L UE ) ;
4 t e m a1 . s e t C o r D aF o n t e ( C ol o r . B L AC K ) ;
56 Tema tema2 = ne w Tema();
7 t em a2 . s et No me ("Fire" );
8 t e m a2 . s e t C o r D oF u n d o ( C ol o r . R ED ) ;
9 t e m a2 . s e t C o r D aF o n t e ( C ol o r . W H IT E ) ;
Código Java 2.65: Tema.java
Queremos controlar os temas criados de maneira centralizada e acessá-los de qualquer ponto daaplicação garantindo que exista apenas uma instância de cada tema. Podemos expandir a propostado padrão Singleton para resolver esse problema.
O construtor da classe Tema deve ser privado para que os objetos não sejam criados em qualquer
lugar da aplicação. Além disso, essa classe deve disponibilizar um método para que as instânciaspossam ser acessadas globalmente.
1 p u b li c c l a ss T em a {
2 private S t r in g n o me ;
3 private C o l or c o r D oF u n d o ;
4 private C o l or c o r D aF o n t e ;
5
6 p r i va t e s t a ti c M ap < S t r i ng , T em a > t e m as = ne w HashMap <String , Tema >();
7
8 p u b li c s t a ti c f i n al S t ri n g S KY = "Sky" ;
9 p u b li c s t a ti c f i n al S t ri n g F IR E = "Fire" ;
1
11 static {
12 Tema tema1 = ne w Tema();
13 tema1 .setNome (Tema .SKY );14 te ma1 . se tCo rD oFu nd o( Col or .BLUE );
15 te ma1 . se tCo rD aFo nt e( Col or .BL ACK );
32 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 37/121
33 P ADRÕES DE CRIAÇÃO
16
17 Tema tema2 = ne w Tema();
18 tema2 .setNome (Tema .FIRE );
19 tema2 .setCorDoFundo (Color .RED );
2 te ma2 . se tCo rD aFo nt e( Col or .WH ITE );
2122 temas .put (tema1 .getNome () , tema1 );
23 temas .put (tema2 .getNome () , tema2 );
24 }
25
26 private T em a () {
27 }
28
29 p u b li c s t a ti c T e ma g e t I ns t a n ce ( S t r i n g n o m e Do T e m a ) {
3 return Tema.temas.get(nomeDoTema);
31 }
32
33 / / G E T TE R S A N D S E T T E R S
34 }
Código Java 2.66: Tema.java
Organização
O diagrama UML abaixo ilustra a organização desse padrão.
Figura 2.10: UML do padrão Multiton
O personagem desse padrão é:
Multiton (Tema)Classe que permite a criação de uma quantidade limitada de instâncias e fornece um métodoestático para recuperá-las.
Exercícios de Fixação
29 Crie um projeto chamado Multiton.
30 Crie a classe Tema e pré defina os temas “Fire” e “Sky” utilizando o padrão Multiton.
1 p u b li c c l a ss T em a {
2 private S t r in g n o me ;
3 private C o l or c o r D oF u n d o ;
4 private C o l or c o r D aF o n t e ;
5
6 p r i va t e s t a ti c M ap < S t r i ng , T em a > t e m as = ne w HashMap <String , Tema >();
7
8 p u b li c s t a ti c f i n al S t ri n g S KY = "Sky" ;9 p u b li c s t a ti c f i n al S t ri n g F IR E = "Fire" ;
1
www.k19.com.br 33
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 38/121
P ADRÕES DE CRIAÇÃO 34
11 static {
12 Tema tema1 = ne w Tema();
13 tema1 .setNome (Tema .SKY );
14 te ma1 . se tCo rD oFu nd o( Col or .BLUE );
15 te ma1 . se tCo rD aFo nt e( Col or .BL ACK );
1617 Tema tema2 = ne w Tema();
18 tema2 .setNome (Tema .FIRE );
19 tema2 .setCorDoFundo (Color .RED );
2 te ma2 . se tCo rD aFo nt e( Col or .WH ITE );
21
22 temas .put (tema1 .getNome () , tema1 );
23 temas .put (tema2 .getNome () , tema2 );
24 }
25
26 private T em a () {
27 }
28
29 p u b li c s t a ti c T e ma g e t I ns t a n ce ( S t r i n g n o m e Do T e m a ) {
3 return Tema.temas.get(nomeDoTema);
31 }
32
33 public S t r in g g e t No m e ( ) {
34 return nome;
35 }
36
37 p u b li c v o id s e t No m e ( S t r in g n o me ) {
38 this . n om e = n om e ;
39 }
4
41 public C o l or g e t C or D o F un d o ( ) {
42 return corDoFundo;
43 }
44
45 p u b li c v o id s e t C or D o F un d o ( C o l or c o r D oF u n do ) {
46 this . c o r D o Fu n d o = c o r D oF u n d o ;
47 }48
49 public C o l or g e t C or D a F on t e ( ) {
5 return corDaFonte;
51 }
52
53 p u b li c v o id s e t C or D a F on t e ( C o l or c o r D aF o n te ) {
54 this . c o r D a Fo n t e = c o r D aF o n t e ;
55 }
56 }
Código Java 2.67: Tema.java
31 Teste a classe Tema .
1 p u b li c c l a ss T e s ta T e m a {
2 p u b li c s t a ti c v o id m a i n ( S tr i n g [] a r gs ) {
3 Tema te ma Fi re = Tema . ge tIn st an ce ( Tema .FIRE );
4 System . out . println ( " T em a " + t e m aF i r e . g e t No m e ( ) ) ;
5 System . out . println ( " Co r D a F on te : " + t e m aF i r e . g e t Co r D a Fo n t e ( ) ) ;
6 System . out . println ( " Co r D o F un do : " + t e m aF i r e . g e t Co r D o Fu n d o ( ) ) ;
7
8 Tema te maF ire 2 = Tema . get Ins ta nc e( Tema .FIRE );
9
1 System . out . println ( "--------" );
11 System . out . println ( " C o m p a ra n d o a s r e f er ê n c ia s . . . ") ;
12 S yst em .out .pr in tl n( te maF ir e == te maF ire 2) ;
13 }
14 }
Código Java 2.68: TestaTema.java
34 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 39/121
35 P ADRÕES DE CRIAÇÃO
Object Pool (não GoF)
Objetivo: Possibilitar o reaproveitamento de objetos.
Considere a seguinte situação. Pretendemos ir a um restaurante sem ter, contudo, efetuado umareserva. Ao chegar no restaurante, podemos nos deparar com duas situações: (i) há pelo menos umamesa livre e podemos nos sentar ou (ii) todas as mesas estão ocupadas e precisamos esperar até queuma mesa seja liberada.
Obviamente, a quantidade de mesas do restaurante é limitada. Além disso, o restaurante aco-moda um número máximo de pessoas por limitações físicas ou para seguir a legislação.
Figura 2.11: Clientes chegando a um restaurante
www.k19.com.br 35
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 40/121
P ADRÕES DE CRIAÇÃO 36
Essa é uma situação típica em que recursos limitados devem ser reutilizados. O restaurante nãoadquire novas mesas a medida que clientes chegam ao restaurante e as mesas são reutilizadas pornovos clientes assim que são liberadas.
Exemplo prático
Estamos desenvolvendo um sistema para uma empresa com uma quantidade muito grande deprojetos. Esse sistema deve controlar os recursos utilizados nos projetos. De maneira genérica, umrecurso pode ser um funcionário, uma sala, um computador, um carro, etc.
Podemos implementar classes especializadas no controle de cada tipo de recurso utilizado nosprojetos. Além disso, seria interessante padronizar essas classes através de uma interface.
1 public interface P oo l < T > {
2 T acquire () ;
3 void r e l ea s e ( T t ) ;4 }
Código Java 2.69: Pool.java
1 p u b li c c l a ss FuncionarioPool implements Pool< Funcionario > {
2 private Collection <Funcionario > funcionarios;
3
4 public F u n c io n a r io P o o l ( ) {
5 / / i n i c il i a za a c o l eç ã o d e f u n c io n á r io s
6 }
7
8 public F u n c io n a r io a c q ui r e ( ) {
9 / / e s co l he u m f u nc i on á ri o d a c o le ç ão
1 }
1112 p u b li c v o id r e l ea s e ( F u n c io n a r io f ) {
13 / / a d ic i on a o f u nc i on á ri o n a c o le ç ão
14 }
15 }
Código Java 2.70: FuncionarioPool.java
1 p u b li c c l a ss SalaPool implements P oo l < S a la > {
2 private Collection <Sala> salas;
3
4 public S a l aP o o l ( ) {
5 / / i n ic i li a za a c o le ç ão d e s a la s
6 }
7
8 public S a la a c q ui r e ( ) {9 / / e s co l he u ma s a la d a c o le ç ão
1 }
11
12 p u b li c v o id r e l ea s e ( S a la s a la ) {
13 / / a d ic i on a a s al a n a c o le ç ão
14 }
15 }
Código Java 2.71: SalaPool.java
Agora, quando um projeto necessita de um recurso como funcionários ou salas basta utilizar ospools.
1 P oo l < Sa la > p oo lS al as = . ..2 P oo l < F un c io n ar i o > p o ol F un c io n ar i o = . ..
3
36 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 41/121
37 P ADRÕES DE CRIAÇÃO
4 / / o b t en d o o s r e c ur s o s
5 S al a s al a = p oo l Sa l as . a c qu i re ( ) ;
6 F u n c io n a r io f u n c i on a r i o = p o o lF u n c i on a r i o . a c q ui r e ( ) ;
7
8 / / u s an d o o s r e cu r so s
9 ...1
11 / / l i b e ra n d o o s r e c u rs o s
12 p o o lS a l a s . r e le a s e ( s al a ) ;
13 p o o l Fu n c i o na r i o s . r e le a s e ( f u n ci o n ar i o )
Código Java 2.72: interagindo com um pool
Organização
O diagrama UML abaixo ilustra a organização desse padrão.
Figura 2.12: UML do padrão Object Pool
Os personagens desse padrão são:
Product (Emissor)Classe ou interface que define o objeto a ser criado.
ConcreteProduct (EmissorSMS)Uma implementação particular do tipo de objeto a ser criado.
Creator (EmissorCreator)Classe ou interface que define a assinatura do método responsável pela criação do produto.
ConcreteCreator (EmissorAssincronoCreator)Classe que implementa ou sobrescreve o método de criação do produto.
Exercícios de Fixação
www.k19.com.br 37
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 42/121
P ADRÕES DE CRIAÇÃO 38
32 Crie um projeto chamado ObjectPool.
33 Defina as classes Sala e Funcionario.1 p u b li c c l a ss F u n c io n a r io {
2 private S t r in g n o me ;
3
4 public F u n c io n a r io ( S t r i n g n o me ) {
5 this . n om e = n om e ;
6 }
7
8 public S t r in g g e t No m e ( ) {
9 r e t ur n t h is .nome;
1 }
11 }
Código Java 2.73: Funcionario.java
34 Defina a interface Pool.
1 public interface P oo l < T > {
2 T acquire () ;
3 void r e l ea s e ( T t ) ;
4 }
Código Java 2.74: Pool.java
35 Defina a classe FuncionarioPool que implementa a interface Pool.
1 p u b li c c l a ss FuncionarioPool implements Pool< Funcionario > {
2 private List<Funcionario > funcionarios;
34 public F u n c io n a r io P o o l ( ) {
5 this . f u n c i on a r i os = ne w ArrayList <Funcionario >();
6 this .funcionarios.add( ne w Funcionario(" M a r c el o M a r ti n s ")) ;
7 this .funcionarios.add( ne w Funcionario(" R a f a el C o s e nt i n o ")) ;
8 this .funcionarios.add( ne w Funcionario(" J o n as H i r at a ")) ;
9
1 }
11
12 public F u n c io n a r io a c q ui r e ( ) {
13 if ( this . f u n c i on a r i os . s i z e ( ) > ) {
14 r e t ur n t h is .funcionarios.remove();
15 }
16 else {
17 r e t ur n n u ll ;
18 }
19 }
2
21 p u b li c v o id r e l ea s e ( F u n c io n a r io f u n c io n a r io ) {
22 this .funcionarios.add(funcionario);
23 }
24 }
Código Java 2.75: FuncionarioPool.java
36 Teste a classe FuncionarioPool.
1 p u b li c c l a ss T e s t a Fu n c i on a r i o Po o l {
2 p u b li c s t a ti c v o id m a i n ( S tr i n g [] a r gs ) {
3 Pool < Funcionario > funcionarioPool = ne w FuncionarioPool();
4 F un ci on ar io f un ci on ar io = f un ci on ar io Po ol . ac qu ir e () ;5 while ( f u n c i on a r i o ! = null ) {
6 System .out .println (funcionario .getNome () );
38 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 43/121
39 P ADRÕES DE CRIAÇÃO
7 funcionario = funcionarioPool .acquire () ;
8 }
9 }
1 }
Código Java 2.76: TestaFuncionarioPool.java
www.k19.com.br 39
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 44/121
P ADRÕES DE CRIAÇÃO 40
40 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 45/121
P ADRÕES ESTRUTURAIS
C A P
Í T U
L O
3 As interações entre os objetos de um sistema podem gerar fortes dependências entre esses ele-mentos. Essas dependências aumentam a complexidade das eventuais alterações no funcionamentodo sistema. Consequentemente, o custo de manutenção aumenta. Mostraremos alguns padrões deprojeto que diminuem o acoplamento entre os objetos de um sistema orientado a objetos.
Veja abaixo um resumo do objetivo de cada padrão estrutural.
Adapter Permitir que um objeto seja substituído por outro que, apesar de realizar a mesma tarefa,possui uma interface diferente.
Bridge Separar uma abstração de sua representação, de forma que ambos possam variar e produzirtipos de objetos diferentes.
Composite Agrupar objetos que fazem parte de uma relação parte-todo de forma a tratá-los semdistinção.
Decorator Adicionar funcionalidade a um objeto dinamicamente.
Facade Prover uma interface simplificada para a utilização de várias interfaces de um subsistema.
Front Controller Centralizar todas as requisições a uma aplicação Web.
Flyweight Compartilhar, de forma eficiente, objetos que são usados em grande quantidade.
Proxy Controlar as chamadas a um objeto através de outro objeto de mesma interface.
Adapter
Objetivo: Permitir que um objeto seja substituído por outro que, apesar de realizar a mesma tarefa,
possui uma interface diferente.
No Brasil, mais de dez tipos de tomadas e plugues eram comercializados. Em 2007, um novopadrão para os plugues e tomadas foi definido pela ABNT. Em 2011, tornou-se permitida somente avenda de produtos que seguiam o novo padrão de dois ou três pinos redondos.
No entanto, muitos consumidores ainda não estão preparados para o novo padrão e possuemtomadas incompatíveis principalmente com os plugues de três pinos.
Por outro lado, há também os casos em que a tomada segue o novo padrão mas o plugue do
aparelho não o segue. Esse pode ser o caso de aparelhos adquiridos antes da nova lei entrar em vigorou adquiridos fora do Brasil.
www.k19.com.br 41
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 46/121
P ADRÕES ESTRUTURAIS 42
Nesses casos, uma solução é usar um adaptador. Veja a figura abaixo.
Figura 3.1: Plugue do notebook incompatível com o novo padrão de tomada
Essa é a essência do padrão Adapter.
Exemplo prático
Estamos realizando manutenção no sistema de gerenciamento de uma determinada empresa. Ocontrole de ponto desse sistema possui diversas limitações. Essas limitações causam muitos prejuí-zos. Principalmente, prejuízos financeiros.
Uma empresa parceira implementou uma biblioteca Java para controlar a entrada e saída dosfuncionários. Essa biblioteca não possui as limitações que existem hoje no sistema que estamosrealizando manutenção. Os diretoresdecidiramque a melhor estratégiaseria adquirir essabibliotecae implantá-la no sistema.
Para implantar essa biblioteca, teremos que substituir as classes que atualmente cuidam do con-trole de ponto pelas classes dessa biblioteca. A complexidade dessa substituição é alta pois os méto-
42 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 47/121
43 P ADRÕES ESTRUTURAIS
dos das classes antigas não são compatíveis com os métodos das classes novas. Em outras palavras,as interfaces são diferentes.
Para tentar minimizar o impacto dessa substituição no código do sistema, podemos definir clas-
ses intermediárias para adaptar as chamadas às classes da biblioteca que foi adquirida.
Por exemplo, atualmente, a entrada de um funcionário é registrada da seguinte maneira:
1 C o nt r ol e De P on t o c o nt r ol e De P on t o = ne w ControleDePonto();
2 F u nc i on a ri o f u nc i on a ri o = .. .
3 c o n t ro l e D e Po n t o . r e g i s tr a E n tr a d a ( f u n c io n a r io ) ;
Código Java 3.1: Registrando a entrada de um funcionário - atualmente
Utilizando as classes da nova biblioteca, a entrada de um funcionário deveria ser registrada as-sim:
1 C o nt r ol e De P on t oN o vo c o nt r ol e De P on t oN o vo = . ..
2 F u nc i on a ri o f u nc i on a ri o = .. .
3
4 / / t ru e i n di c a e n tr a da e f a ls e i nd i ca s a íd a
5 c o n t r ol e D e Po n t o N ov o . r e g i s tr a ( f u n c i on a r i o . g e tC o d i go ( ) , true );
Código Java 3.2: Registrando a entrada de um funcionário - com a nova biblioteca
Para diminuir o impacto no código do sistema, podemos criar o seguinte adaptador:
1 p u b li c c l a ss ControleDePontoAdapter extends C o n t ro l e D e Po n t o {
2 private ControleDePontoNovo controleDePontoNovo;
34 p u b li c v o id r e g i st r a E nt r a d a ( F u n ci o n a ri o f u n c io n a r io ) {
5 this .controleDePontoNovo.registra(funcionario.getCodigo(), true );
6 }
7 }
Código Java 3.3: ControleDePontoAdapter.java
Podemos utilizar o adaptador como se estivéssemos utilizando o controle de ponto antigo.
1 C o nt r ol e De P on t o c o nt r ol e De P on t o = ne w ControleDePontoAdapter();
2 F u nc i on a ri o f u nc i on a ri o = .. .
3 c o n t ro l e D e Po n t o . r e g i s tr a E n tr a d a ( f u n c io n a r io ) ;
Código Java 3.4: Registrando a entrada de um funcionário - adaptador
Dessa forma, o código do sistema atual deve ser modificado apenas no trecho em que a classeresponsável pelo controle de ponto é instanciada.
Organização
O diagrama UML abaixo ilustra a organização desse padrão.
www.k19.com.br 43
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 48/121
P ADRÕES ESTRUTURAIS 44
Figura 3.2: UML do padrão Adapter
Os personagens desse padrão são:
Target (ControleDePonto)Define a interface utilizada pelo Client.
Adaptee (ControleDePontoNovo)Classe que define o novo objeto a ser utilizado.
Adapter (ControleDePontoAdapter)Classe que implementa a interface definida pelo Target e adapta as chamadas do Client parao Adaptee.
ClientInterage com os objetos através da interface definida por Target.
Exercícios de Fixação
1 Crie um projeto chamado Adapter.
2 Defina uma classe Funcionario.
1 p u b li c c l a ss F u n c io n a r io {
2 private S t r in g n o me ;
3
4 public F u n c io n a r io ( S t r i n g n o me ) {5 this . n om e = n om e ;
6 }
7
8 public S t r in g g e t No m e ( ) {
9 return nome;
1 }
11 }
Código Java 3.5: Funcionario.java
3 Defina uma classe ControleDePonto.
1 p u b li c c l a ss C o n t ro l e D eP o n t o {
2 p u b li c v o id r e g i st r a E nt r a d a ( F u n ci o n a ri o f ) {
3 Ca le nd ar ca le nd ar = C al en da r. ge tIn st an ce () ;4 SimpleDateFormat simpleDateFormat = ne w SimpleDateFormat(
5 " d d / M M / yy y y H : m : s ");
44 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 49/121
45 P ADRÕES ESTRUTURAIS
6 S tr in g f or ma t = s im pl eD at eF or ma t .f or ma t( ca le nd ar . ge tT im e () );
7 System . out . println ( " E n t r ad a : " + f . g et N om e ( ) + " à s " + f o r ma t ) ;
8 }
9
1 p u b li c v o id r e g i st r a S ai d a ( F u n c io n a r io f ) {
11 Ca le nd ar ca le nd ar = C al en da r. ge tIn st an ce () ;12 SimpleDateFormat simpleDateFormat = ne w SimpleDateFormat(
13 " d d / M M / yy y y H : m : s ");
14 S tr in g f or ma t = s im pl eD at eF or ma t .f or ma t( ca le nd ar . ge tT im e () );
15 System . out . println ( " S aí d a : " + f . g et N om e ( ) + " à s " + f o r ma t ) ;
16 }
17 }
Código Java 3.6: ControleDePonto.java
4 Defina uma classe para testar o controle de ponto.
1 p u b li c c l a ss T e s t e Co n t r ol e D e P on t o {
2 p u b li c s t a ti c v o id m a i n ( S tr i n g [] a r gs ) throws I n t e rr u p t e dE x c e p ti o n {
3 ControleDePonto controleDePonto = ne w ControleDePonto();
4 Funcionario funcionario = ne w Funcionario(" M a r c el o M a r ti n s ");
5 c on tr ol eD eP on to . re gi st ra En tr ad a( f un ci on ar io ) ;
6 Thread . sleep (3) ;
7 c on tr ol eD eP on to . re gi st ra Sa id a (f un ci on ar io ) ;
8 }
9 }
Código Java 3.7: TesteControleDePonto.java
5 Defina uma classe ControleDePontoNovo.
1 p u b li c c l a ss C o n t r ol e D e Po n t o N ov o {
2 p u b li c v o id r e g i st r a ( F u n c io n a r io f , boolean e n t ra d a ) {
3 Ca le nd ar ca le nd ar = C al en da r. ge tIn st an ce () ;
4 SimpleDateFormat simpleDateFormat = ne w SimpleDateFormat(5 " d d / M M / yy y y H : m : s ");
6 S tr in g f or ma t = s im pl eD at eF or ma t .f or ma t( ca le nd ar . ge tT im e () );
7
8 if ( e n t r ad a = = true ) {
9 System . out . println (" E n t r ad a : " + f . g et N om e ( ) + " à s " + f o r ma t ) ;
1 } else {
11 System . out . println (" S a íd a : " + f . g et N om e ( ) + " à s " + f o r ma t ) ;
12 }
13 }
14 }
Código Java 3.8: ControleDePontoNovo.java
6 Defina uma classe adaptador para a nova classe ControleDePontoNovo.
1 p u b li c c l a ss ControleDePontoAdapter extends C o n t ro l e D e Po n t o {
2 private ControleDePontoNovo controleDePontoNovo;
3
4 public C o n t ro l e D e Po n t o A da p t e r ( ) {
5 this . c o n t r o l eD e P o n to N o v o = ne w ControleDePontoNovo();
6 }
7
8 p u b li c v o id r e g i st r a E nt r a d a ( F u n ci o n a ri o f ) {
9 this .controleDePontoNovo.registra(f, true );
1 }
11
12 p u b li c v o id r e g i st r a S ai d a ( F u n c io n a r io f ) {
13 this .controleDePontoNovo.registra(f, false );
14 }
15 }
Código Java 3.9: ControleDePontoAdapter.java
www.k19.com.br 45
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 50/121
P ADRÕES ESTRUTURAIS 46
7 Altere a classe de teste do controle de ponto para utilizar o adapter.
1 p u b li c c l a ss T e s t e Co n t r ol e D e P on t o {
2 p u b li c s t a ti c v o id m a i n ( S tr i n g [] a r gs ) throws I n t e rr u p t e dE x c e p ti o n {
3 ControleDePonto controleDePonto = ne w ControleDePontoAdapter();
4 Funcionario funcionario = ne w Funcionario(" M a r c el o M a r ti n s ");5 c on tr ol eD eP on to . re gi st ra En tr ad a( f un ci on ar io ) ;
6 Thread . sleep (3) ;
7 c on tr ol eD eP on to . re gi st ra Sa id a (f un ci on ar io ) ;
8 }
9 }
Código Java 3.10: TesteControleDePonto.java
Bridge
Objetivo: Separar uma abstração de sua representação, de forma que ambos possam variar e pro-
duzir tipos de objetos diferentes.
Hoje em dia, os celulares utilizam cartões SIM (subscriber identity module ). Entre outros dados,esses cartões armazenam o número do telefone, a chave de autenticação do cliente e um identifica-dor da rede a ser usada na comunicação.
Antes de ser capaz de fazer ligações, o celular precisa passar pelo processo de autenticação. Nesseprocesso, o celular troca informações com a rede móvel a fim de verificar a identidade do usuário.
Além de armazenar toda informação necessária para essa autenticação, o cartão SIM é quem defato executa os algoritmos de criptografia usados nesse processo, e não o aparelho celular. Uma vezque a autenticação é feita, o celular torna-se capaz de fazer ligações.
A maioria dos celulares disponíveis hoje em dia é capaz de lidar com diversas operadoras, bas-tando apenas que o cartão SIM do celular seja substituído. Essa é uma das vantagens dessa tecnolo-gia.
Se o seu aparelho celular estiver danificado ou sem bateria, você pode simplesmente remover
o cartão SIM do aparelho e colocá-lo em outro. Por outro lado, se você viajar para outro país, porexemplo, você pode levar o seu aparelho celular e adquirir um cartão SIM de uma operadora local.
46 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 51/121
47 P ADRÕES ESTRUTURAIS
Figura 3.3: Diversas combinações de celular/operadora
A possibilidade de combinar os cartões SIM e os aparelhos celulares de forma independente é acaracterística principal proposta pelo padrão Bridge.
Exemplo prático
Estamos desenvolvendo um sistema que deve gerar diversos tipos de documentos (recibos, ates-tados, comunicados, etc) em diversos formatos de arquivos (txt, html, pdf, etc).
Podemos definir uma interface para padronizar os diversos tipos de documentos que o nossosistema pode suportar.
1 public interface D o c um e n t o {
2 void geraArquivo();
3 }
Código Java 3.11: Documento.java
Com a interface criada, podemos definir tipos específicos de documentos.
www.k19.com.br 47
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 52/121
P ADRÕES ESTRUTURAIS 48
1 p u b li c c l a ss Recibo implements D o c um e n t o {
2 p r i va t e d o u bl e valor;
3
4 p u b li c v o id g e r aA r q u iv o ( ) {
5 / / c ri a u m a r qu i vo c om o s d a do s d es se r e ci b o e m u m f o rm a to s u po r ta d o6 }
7 }
Código Java 3.12: Recibo.java
Dessa forma, a lógica dos documentos seria definida nas classes que implementam a interfaceDocumento. Para dividir melhor as responsabilidades, podemos implementar a lógica dos formatosde arquivos que o sistema suportará em outras classes. Inclusive, podemos definir uma interfacepara padronizar essas classes.
1 public interface G e r a do r D e A rq u i v o {
2 p u b li c v o id g e ra ( S t r i ng c o n te u d o ) ;
3 }
Código Java 3.13: GeradorDeArquivo.java
1 p u b li c c l a ss GeradorDeArquivoTXT implements G e r a d or D e A r qu i v o {
2 p u b li c v o id g e ra ( S t r i ng c o n te u d o ) {
3 / / p r oc e ss o p ar a g e ra r u m a r qu i vo t xt c om o c o nt e ud o d o p a râ m et r o
4 }
5 }
Código Java 3.14: GeradorDeArquivoTXT.java
1 p u b li c c l a ss GeradorDeArquivoHTML implements G e r a d or D e A rq u i v o {
2 p u b li c v o id g e ra ( S t r i ng c o n te u d o ) {
3 / / p r oc e ss o p ar a g e ra r u m a r qu i vo H TM L c om o c o nt e ud o d o p a râ m et r o
4 }
5 }
Código Java 3.15: GeradorDeArquivoHTML.java
Por fim, os documentos devem ser associados aos geradores de arquivos. Isso pode ser realizadoatravés de construtores nas classes específicas de documentos.
1 p u b li c c l a ss Recibo implements D o c um e n t o {
2 p r i va t e d o u bl e valor;
3
4 private GeradorDeArquivo gerador;
5
6 public R e c ib o ( G e r a d or D e A r qu i v o g e r ad o r ) {
7 this . g e r a do r = g e r ad o r ;
8 }
9
1 p u b li c v o id g e r aA r q u iv o ( ) {
11 String conteudoDesseRecibo = ...
12 this .gerador.gera(conteudoDesseRecibo)
13 }
14 }
Código Java 3.16: Recibo.java
Agora, podemos exportar um recibo em txt da seguinte forma:
1 G e ra d or D eA r qu i vo T XT g e r ad o r = ne w GeradorDeArquivoTXT();
23 R ec ib o re ci bo = ne w Recibo(gerador);
4
48 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 53/121
49 P ADRÕES ESTRUTURAIS
5 r ec i bo . g e r aA r qu i vo ( ) ;
Código Java 3.17: Exportando um recibo em txt
Organização
O diagrama UML abaixo ilustra a organização desse padrão.
Figura 3.4: UML do padrão Bridge
Os personagens desse padrão são:
Abstraction (Documento)Define a interface de um determinado tipo de objeto.
RefinedAbstraction (Recibo)Uma implementação particular do Abstraction quedelegaaum Implementor a realização dedetermindas tarefas.
Implementor (GeradorDeArquivo)Define a interface dos objetos que serão acionados pelos Abstractions.
ConcreteImplementor (GeradorDeArquivoTXT , GeradorDeArquivoHTML) uma implementação es-pecífica do Implementor
Client
Interage com as Abstractions.
Exercícios de Fixação
8 Crie um projeto chamado Bridge.
9 Crie uma interface Documento.
1 public interface D o c um e n t o {
2 void geraArquivo();
3 }
Código Java 3.18: Documento.java
www.k19.com.br 49
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 54/121
P ADRÕES ESTRUTURAIS 50
10 Crie uma classe Recibo que gera um arquivo txt.
1 p u b li c c l a ss Recibo implements D o c um e n t o {
2 private S t r in g e m i ss o r ;
3 private S t r in g f a v o re c i do ;
4 p r i va t e d o u bl e valor;5
6 public Recibo(String emissor , String favorecido , double v a lo r ) {
7 this . e m i s so r = e m i ss o r ;
8 this . f a v o r ec i d o = f a v o re c i d o ;
9 this . v a lo r = v a lo r ;
1 }
11
12 p u b li c v o id g e r aA r q u iv o ( ) {
13 tr y {
14 PrintStream saida = ne w PrintStream("recibo.txt" );
15 saida . println (" R e ci b o : " );
16 saida . println (" E m p r es a : " + this .emissor);
17 saida . println (" C l i e nt e : " + this .favorecido);
18 saida . println (" V a lo r : " + this .valor);
19 } catch ( F i l e N o t Fo u n d Ex c e p t io n e ) {
2 e. printStackTrace () ;
21 }
22 }
23 }
Código Java 3.19: Recibo.java
11 Teste a classe Recibo.
1 p u b li c c l a ss T e s t eR e c i bo {
2 p u b li c s t a ti c v o id m a i n ( S tr i n g [] a r gs ) {
3 Recibo recibo = ne w Recibo(" K 1 9 T r e i na m e n to s " , " M a r c el o M a r ti n s ", 1 ) ;
4 recibo . geraArquivo () ;
5 }
6 }
Código Java 3.20: TesteRecibo.java
12 A classe Recibo somente gera arquivo no formato txt. Para suportar mais formatos, podemosdefinir a lógica de gerar arquivos em diversos formatos em outras classes. Vamos padronizar estasclasses através de uma interface.
1 public interface G e r a do r D e A rq u i v o {
2 p u b li c v o id g e ra ( S t r i ng c o n te u d o ) ;
3 }
Código Java 3.21: GeradorDeArquivo.java
13 Crie uma classe GeradorDeArquivoTXT que implementa a interface GeradorDeArquivo.
1 p u b li c c l a ss GeradorDeArquivoTXT implements G e r a d or D e A r qu i v o {
2 p u b li c v o id g e ra ( S t r i ng c o n te u d o ) {
3 tr y {
4 PrintStream saida = ne w PrintStream("arquivo.txt" ) ;
5 saida . println ( conteudo );
6 saida . close () ;
7 } catch ( F i l e N o t Fo u n d Ex c e p t io n e ) {
8 e. printStackTrace () ;
9 }
1 }
11 }
Código Java 3.22: GeradorDeArquivoTXT.java
50 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 55/121
51 P ADRÕES ESTRUTURAIS
14 Associe os geradores de arquivos aos documentos. Altere a classe Recibo para receber um gera-dor de arquivo como parâmetro no construtor.
1 p u b li c c l a ss Recibo implements D o c um e n t o {
2 private S t r in g e m i ss o r ;
3 private S t r in g f a v o re c i do ;
4 p r i va t e d o u bl e valor;
5 private GeradorDeArquivo geradorDeArquivo;
6
7 public Recibo(String emissor , String favorecido , double valor,
8 GeradorDeArquivo geradorDeArquivo ) {
9 this . e m i s so r = e m i ss o r ;
1 this . f a v o r ec i d o = f a v o re c i d o ;
11 this . v a lo r = v a lo r ;
12 this . g e r a d o rD e A r q ui v o = g e r a d or D e A rq u i v o ;
13 }
14
15 p u b li c v o id g e r aA r q u iv o ( ) {
16 StringBuffer buffer = ne w StringBuffer();
17 buffer . append (" R e ci b o : " );
18 buffer . append ("\n" ) ;19 buffer . append (" E m p r es a : " + this .emissor);
2 buffer . append ("\n" ) ;
21 buffer . append (" C l i e nt e : " + this .favorecido);
22 buffer . append ("\n" ) ;
23 buffer . append (" V a lo r : " + this .valor);
24 buffer . append ("\n" ) ;
25 this .geradorDeArquivo.gera(buffer.toString());
26 }
27 }
Código Java 3.23: Recibo.java
15 Teste a classe a classe Recibo e associe com o gerador de arquivo txt.
1 p u b li c c l a ss T e s t eR e c i bo {
2 p u b li c s t a ti c v o id m a i n ( S tr i n g [] a r gs ) {
3 GeradorDeArquivo geradorDeArquivoTXT = ne w GeradorDeArquivoTXT();
4 Recibo recibo = ne w Recibo(" K 1 9 T r e i na m e n to s " , " M a r c el o M a r ti n s ", 1 ,
5 geradorDeArquivoTXT ) ;
6 recibo . geraArquivo () ;
7 }
8 }
Código Java 3.24: TesteRecibo.java
Composite
Objetivo: Agrupar objetos que fazem parte de uma relação parte-todo de forma a tratá-los sem
distinção.
Exemplo prático
Suponha que estamos desenvolvendo um sistema para calcular um caminho entre quaisquer
dois pontos do mundo. Um caminho pode ser percorrido de diversas maneiras: à pé, de carro, deônibus, de trem, de avião, de navio, etc.
www.k19.com.br 51
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 56/121
P ADRÕES ESTRUTURAIS 52
Figura 3.5: Viagem de Natal-RN para São Paulo
52 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 57/121
53 P ADRÕES ESTRUTURAIS
O sistema deve apresentar graficamente para os usuários as rotas que forem calculadas. Cadatipo de trecho deve ser apresentado de uma maneira específica. Por exemplo, se o trecho for decaminhada então deve aparecer na impressão da rota a ilustração de uma pessoa andando.
Cada tipo de trecho pode ser implementado por uma classe e seria interessante definir uma in-terface para padronizá-las.
1 public interface T r e ch o {
2 void imprime();
3 }
Código Java 3.25: Trecho.java
1 p u b li c c l a ss TrechoAndando implements T r e ch o {
2 / / a t ri b ut o s e m e to d os
3
4 p u b li c v o id i m p ri m e ( ) {
5 / / i m pr i me n a t el a a s i n fo r ma ç õe s d es s e t re c ho a n da n do .
6 }7 }
Código Java 3.26: TrechoAndando.java
1 p u b li c c l a ss TrechoDeCarro implements T r e ch o {
2 / / a t ri b ut o s e m e to d os
3
4 p u b li c v o id i m p ri m e ( ) {
5 / / i m pr i me n a t el a a s i n fo r ma ç õe s d es s e t re c ho d e c ar r o .
6 }
7 }
Código Java 3.27: TrechoDeCarro.java
O próprio caminho entre dois pontos pode ser considerado um trecho. Basicamente, um cami-nho é um trecho composto por outros trechos.
1 p u b li c c l a ss Caminho implements T r e ch o {
2 private List<Trecho > trechos = ne w ArrayList <Trecho >();
3
4 p u b li c v o id a d i c io n a ( T r e ch o t r e ch o ) {
5 this .trechos.add(trecho);
6 }
7
8 p u b li c v o id r e m ov e ( T r e ch o t r e ch o ) {
9 this .trechos.remove(trecho);
1 }
11
12 p u b li c v o id i m p ri m e ( ) {13 / / i m pr i me n a t el a a s i n fo r ma ç õe s d es s e c a mi n ho .
14 }
15 }
Código Java 3.28: Caminho.java
O processo de construção de um caminho envolveria a criação ou a recuperação de trechos dequaisquer tipo para compor um trecho maior.
1 T re ch o t re ch o1 = . ..
2 T re ch o t re ch o2 = . ..
3 T re ch o t re ch o3 = . ..
4
5 C am in ho c am in ho 1 = ne w Caminho();6 c a m in h o 1 . a d ic i o n a ( t r ec h o 1 ) ;
7 c a m in h o 1 . a d ic i o n a ( t r ec h o 2 ) ;
www.k19.com.br 53
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 58/121
P ADRÕES ESTRUTURAIS 54
8
9 C am in ho c am in ho 2 = ne w Caminho();
1 c a m in h o 2 . a d ic i o n a ( c a mi n h o1 ) ;
11 c a m in h o 2 . a d ic i o n a ( t r ec h o 3 ) ;
Código Java 3.29: Criando um caminho
Organização
O diagrama UML abaixo ilustra a organização desse padrão.
Figura 3.6: UML do padrão Composite
Os personagens desse padrão são:
Component (Trecho)Interface que define os elementos da composição.
Composite (Caminho)Define os Components que são formados por outros Components.
Leaf (TrechoAndando, TrechoDeCarro)Define os elementos básicos da composição, isto é, aqueles que não são formados por outrosComponents.
Exercícios de Fixação
16 Crie um projeto chamado Composite.
17 Defina uma interface Trecho.
1 public interface T r e ch o {
2 void imprime();
3 }
Código Java 3.30: Trecho.java
18 Defina as classes que implementam a interface Trecho.
54 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 59/121
55 P ADRÕES ESTRUTURAIS
1 p u b li c c l a ss TrechoAndando implements T r e ch o {
2 private S t r in g d i r ec a o ;
3 p r i va t e d o u bl e distancia;
4
5 public TrechoAndando(String direcao , double d i s ta n c i a ) {6 this . d i r e ca o = d i r ec a o ;
7 this . d i s t a nc i a = d i s ta n c i a ;
8 }
9
1 p u b li c v o id i m p ri m e ( ) {
11 System . out . println ( " V á A n da n do : ");
12 System . out . println ( this .direcao);
13 System . out . println ( " A d i st â nc i a p e rc o rr i da s er á d e : " + this . d i s t a nc i a + " ←
metros.");
14 }
15 }
Código Java 3.31: TrechoAndando.java
1 p u b li c c l a ss TrechoDeCarro implements T r e ch o {2 private S t r in g d i r ec a o ;
3 p r i va t e d o u bl e distancia;
4
5 public TrechoDeCarro(String direcao , double d i s ta n c i a ) {
6 this . d i r e ca o = d i r ec a o ;
7 this . d i s t a nc i a = d i s ta n c i a ;
8 }
9
1 p u b li c v o id i m p ri m e ( ) {
11 System . out . println ( " V á d e c a rr o : ");
12 System . out . println ( this .direcao);
13 System . out . println ( " A d i st â nc i a p e rc o rr i da s er á d e : " + this . d i s t a nc i a + " ←
metros.");
14 }
15 }
Código Java 3.32: TrechoDeCarro.java
19 Defina uma classe Caminho que é um Trecho e será composto por um ou mais trechos.
1 p u b li c c l a ss Caminho implements T r e ch o {
2 private List<Trecho > trechos;
3
4 public C a m in h o ( ) {
5 this . t r e c ho s = ne w ArrayList <Trecho >();
6 }
7
8 p u b li c v o id a d i c io n a ( T r e ch o t r e ch o ) {
9 this .trechos.add(trecho);
1 }11
12 p u b li c v o id r e m ov e ( T r e ch o t r e ch o ) {
13 this .trechos.remove(trecho);
14 }
15
16 p u b li c v o id i m p ri m e ( ) {
17 fo r ( T r ec ho t r ec h o : this . t r e c ho s ) {
18 trecho . imprime () ;
19 }
2 }
21 }
Código Java 3.33: Caminho.java
20 Crie uma classe para testar e criar um caminho que é composto por mais de um trecho.
www.k19.com.br 55
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 60/121
P ADRÕES ESTRUTURAIS 56
1 p u b li c c l a ss T e s t aC a m i nh o {
2 p u b li c s t a ti c v o id m a i n ( S tr i n g [] a r gs ) {
3 Trecho trecho1 = ne w TrechoAndando(
4 " V á a t é o c r uz a me n to d a A v . R e b o uç a s c om a A v . Br i ga d ei r o F a ri a L im a ",
5 5) ;
6 Trecho trecho2 = ne w TrechoDeCarro(7 " V á a t é o c r uz a me n to d a A v . B r i g ad e ir o F ar i a L im a c om a A v . Ci d ad e ←
Jardim" ,
8 15) ;
9 Trecho trecho3 = ne w TrechoDeCarro(
1 " V ir e a d i re i ta n a M a rg i na l P i nh e ir o s ", 5 ) ;
11
12 Caminho caminho1 = ne w Caminho();
13 caminho1 .adiciona (trecho1 );
14 caminho1 .adiciona (trecho2 );
15
16 System . out . println ( " C am in ho 1 : ");
17 caminho1 . imprime () ;
18
19 Caminho caminho2 = ne w Caminho();
2 caminho2 .adiciona (caminho1 );
21 caminho2 .adiciona (trecho3 );
22 System . out . println ( "---------------" ) ;
23 System . out . println ( " C a mi n ho 2 : " );
24 caminho2 . imprime () ;
25 }
26 }
Código Java 3.34: TesteCaminho.java
Decorator
Objetivo: Adicionar funcionalidade a um objeto dinamicamente.
Considere um mapa de ruas digital, como o Google Maps, por exemplo. É natural que o mapacontenha os nomes das ruas. Contudo, o mapa também poderia exibir diversas outras informações
(como, por exemplo, relevo, indicadores de estabelecimentos de comércio e serviço), bem como ofe-recer opções para encontrar caminhos entre dois pontos e traçar rotas.
56 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 61/121
57 P ADRÕES ESTRUTURAIS
100m
Av. Rebouças
Av. Rebouças
R. Henrique Monteiro
A v . E u s é b i o M a t o s o
R u a T a v a r e s C a b r a l
A v .
B r i g a d e i r o F a r i a L i m a
100m
Av. Rebouças
Av. Rebouças
R. Henrique MonteiroA v . E u s é b i o M a t o s o
R u a T a v a r e s C a b r a l
A v .
B r i g a d e i r o F a r i a L i m
a$
K19
100m
Av. Rebouças
Av. Rebouças
R. Henrique MonteiroA v . E u s é b i o M a t o s o
R u a T a v a r e s C a b r a l
A v .
B r i g a d e i r o F a r i a L i m a
$
K19
100m
+
_
Figura 3.7: Mapa de ruas com diversos decoradores
Essas opções adicionais são o que chamamos de decorações.
www.k19.com.br 57
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 62/121
P ADRÕES ESTRUTURAIS 58
Exemplo prático
Como exemplo prático do padrão Factory Method, consideramos um sistema de envio de men-
sagens. Nesse exemplo, definimos uma interface para padronizar os emissores.1 public interface E m i ss o r {
2 void envia(String mensagem);
3 }
Código Java 3.35: Emissor.java
Um possível emissor, poderia ser implementado mais ou menos assim:
1 p u b li c c l a ss EmissorBasico implements E m i ss o r {
2 p u b li c v o id e n v ia ( S t r i ng m e n s ag e m ) {
3 System . out . println ( " E n v i an d o u m a m e n s a g e m : " ) ;
4 System .out .println (mensagem );
5 }
6 }
Código Java 3.36: EmissorBasico.java
Agora, suponha que estejamos interessados em adicionar algumas funcionalidades no processode envio de mensagem. Tais funcionalidades incluem criptografia e compressão das mensagens.
Para não alterar as classes que definem os emissores, cada funcionalidade adicional (decoração)será implementada por um novo objeto (decorador).
Quando queremos enviar uma mensagem, não podemos chamar diretamente os emissores, poisas funcionalidades adicionais não serão executadas. Portanto, devemos entregar a mensagem a um
decorador, que executará a tarefa para a qual foi concebido. O decorador, por sua vez, terá tambéma responsabilidade de repassar a mensagem a um emissor para que ela seja enviada. Dessa forma,todo decorador deve possuir um emissor.
O código atual utiliza a interface dos emissores para enviar mensagens. Para não afetar essecódigo, os decoradores devem seguir a mesma interface dos emissores. Assim, quem envia umamensagem através de um emissor, não sabe se este emissor é um decorador. Note que, dessa forma,decoradores podem ser encadeados.
Vamos então definir uma classe abstrata para representar os decoradores de emissores. Nestaclasse, definiremos que todos os decoradores possuirão um emissor.
1 p u b li c a b s t ra c t c l a ss EmissorDecorator implements E m i ss o r {
2 private E m i ss o r e m i ss o r ;
3
4 public E m i s so r D e co r a t o r ( E m is s o r e m i ss o r ) {
5 this . e m i s so r = e m i ss o r ;
6 }
7
8 p u b li c a b s tr a c t v o id e n v ia ( S t r i n g m e n s ag e m ) ;
9
1 public E m i ss o r g e t E mi s s or ( ) {
11 r e t ur n t h is .emissor;
12 }
13 }
Código Java 3.37: EmissorDecorator.java
Agora, podemos implementar alguns decoradores.
58 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 63/121
59 P ADRÕES ESTRUTURAIS
1 p u b li c c l a ss EmissorDecoratorComCriptografia extends E m i s s or D e c o ra t o r {
2 public E m i s s or D e c o ra t o r C om C r i p t og r a f i a ( E m is s o r e m i ss o r ) {
3 super (emissor);
4 }
56 p u b li c v o id e n v ia ( S t r i ng m e n s ag e m ) {
7 System . out . println ( " E n v i an d o m e n sa g e m c r i p to g r a fa d a : " );
8 this .getEmissor().envia(criptografa(mensagem));
9 }
1
11 private S t r in g c r i p to g r a fa ( S t r i n g m e n s ag e m ) {
12 String mensagemCriptografada = ...
13 return mensagemCriptografada;
14 }
15 }
Código Java 3.38: EmissorDecoratorComCriptografia.java
1 p u b li c c l a ss EmissorDecoratorComCompressao extends E m i s so r D e c or a t o r {2
3 public E m i s s or D e c o ra t o r C om C o m p re s s a o ( E m i ss o r e m i ss o r ) {
4 super (emissor);
5 }
6
7 void e n v ia ( S t r i n g m e n sa g e m ) {
8 System . out . println ( " E n v i an d o m e n sa g e m c o m p ri m i d a : " );
9 this .getEmissor().envia(comprime(mensagem));
1 }
11
12 private S t r in g c o m pr i m e ( S t ri n g m e n sa g e m ) {
13 String mensagemComprimida = ...
14 return mensagemComprimida;
15 }
16 }
Código Java 3.39: EmissorDecoratorComCompressao.java
Os decoradores poderiam então ser usados da seguinte forma:
1 S tr in g m en sa ge m = .. .
2
3 / / U m e m is s or q ue a pe n as e n vi a a m e ns a ge m
4 E mi ss or e mi ss or = ne w EmissorBasico();
5 e m is s or . e n vi a ( m en s ag e m );
6
7 / / E m i ss o r q u e e n vi a m e n sa g e n s c r i p to g r a fa d a s
8 emissor = ne w EmissorComCriptografia( ne w EmissorBasico());
9 e m is s or . e n vi a ( m en s ag e m );1
11 / / E m i ss o r q u e e n v i a m e n sa g e n s c r i p t o g r a fa d a s e c o m p ri m i da s
12 e mi ss or = ne w EmissorComCriptografia( ne w EmissorComCompressao( ne w EmissorBasico()));
13 e m i ss o r . e n vi a ( m e n s ag e m ) ;
Código Java 3.40: Emissores com diferentes funcionalidades inseridas dinamicamente
Organização
O diagrama UML abaixo ilustra a organização desse padrão.
www.k19.com.br 59
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 64/121
P ADRÕES ESTRUTURAIS 60
Figura 3.8: UML do padrão Decorator
Os personagens desse padrão são:
Component (Emissor)Define a interface de objetos que possuem determinada tarefa.
ConcreteComponent (EmissorBasico)Implementação particular do Component.
Decorator (EmissorDecorator)Classe abstrata que mantém uma referência para um Component e será utilizada para padroni-zar os objetos decoradores.
ConcreteDecorator (EmissorDecoratorComCriprografia , EmissorDecoratorComCompressao )Implementação de um Decorator.
Exercícios de Fixação
21 Crie um projeto chamado Decorator.22 Defina uma interface Emissor.
1 public interface E m i ss o r {
2 void envia(String mensagem);
3 }
Código Java 3.41: Emissor.java
23 Crie a classe EmissorBasico.
1 p u b li c c l a ss EmissorBasico implements E m i ss o r {
2 p u b li c v o id e n v ia ( S t r i ng m e n s ag e m ) {
3 System . out . println ( " E n v i an d o u m a m e n s a g e m : " ) ;4 System .out .println (mensagem );
5 }
60 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 65/121
61 P ADRÕES ESTRUTURAIS
6 }
Código Java 3.42: EmissorBasico.java
24 Crie uma classe EmissorDecorator para modelar um decorador de emissores.
1 p u b li c a b s t ra c t c l a ss EmissorDecorator implements E m i ss o r {
2 private E m i ss o r e m i ss o r ;
3
4 public E m i s so r D e co r a t o r ( E m is s o r e m i ss o r ) {
5 this . e m i s so r = e m i ss o r ;
6 }
7
8 p u b li c a b s tr a c t v o id e n v ia ( S t r i n g m e n s ag e m ) ;
9
1 public E m i ss o r g e t E mi s s or ( ) {
11 r e t ur n t h is .emissor;
12 }
13 }
Código Java 3.43: EmissorDecorator.java
25 Crie um decorador que envia mensagens criptografadas e outro que envia mensagens compri-midas.
1 p u b li c c l a ss EmissorDecoratorComCriptografia extends E m i s s or D e c o ra t o r {
2
3 public E m i s s or D e c o ra t o r C om C r i p t og r a f i a ( E m is s o r e m i ss o r ) {
4 super (emissor);
5 }
6
7 void e n v ia ( S t r i n g m e n sa g e m ) {
8 System . out . println ( " E n v i an d o m e n sa g e m c r i p to g r a fa d a : " );
9 this .getEmissor().envia(criptografa(mensagem));1 }
11
12 private S t r in g c r i p to g r a fa ( S t r i n g m e n s ag e m ) {
13 String mensagemCriptografada = ne w StringBuilder(mensagem).reverse().toString←
() ;
14 return mensagemCriptografada;
15 }
16 }
Código Java 3.44: EmissorDecoratorComCriptografia.java
1 p u b li c c l a ss EmissorDecoratorComCompressao extends E m i s so r D e c or a t o r {
2
3 public E m i s s or D e c o ra t o r C om C o m p re s s a o ( E m i ss o r e m i ss o r ) {
4 super (emissor);5 }
6
7 void e n v ia ( S t r i n g m e n sa g e m ) {
8 System . out . println ( " E n v i an d o m e n sa g e m c o m p ri m i d a : " );
9 String mensagemComprimida ;
1 tr y {
11 mensagemComprimida = comprime (mensagem );
12 } catch ( I O Ex c ep t io n e ) {
13 mensagemComprimida = mensagem ;
14 }
15 this .getEmissor().envia(mensagemComprimida);
16 }
17
18 private S t r in g c o m pr i m e ( S t ri n g m e n sa g e m ) throws I O E x ce p t i on {
19 ByteArrayOutputStream out = ne w ByteArrayOutputStream();
2 DeflaterOutputStream dout = ne w DeflaterOutputStream(out, ne w Deflater());21 dout .w rite ( men sa ge m. get By te s() );
22 dout . close () ;
www.k19.com.br 61
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 66/121
P ADRÕES ESTRUTURAIS 62
23 r e t ur n n e w String(out.toByteArray());
24 }
25 }
Código Java 3.45: EmissorDecoratorComCompressao.java
26 Teste os decoradores.
1 p u b li c c l a ss T e s t e Em i s s o rD e c o ra t o r {
23 p u b li c s t a ti c v o id m a i n ( S tr i n g [] a r gs ) {
4 String mensagem = " ";
5
6 Emissor emissorCript = ne w EmissorComCriptografia( ne w EmissorBasico());
7 emissorCript .envia (mensagem );
8
9 Emissor emissorCompr = ne w EmissorComCompressao( ne w EmissorBasico());
1 emissorCompr .envia (mensagem );
11
12 Emissor emissorCriptCompr = ne w EmissorComCriptografia( ne w ←
EmissorComCompressao( ne w EmissorBasico()));
13 e mi ss or Cr ip tCo mp r. envia ( men sa ge m) ;
14 }
15 }
Código Java 3.46: TesteEmissorDecorator.java
Facade
Objetivo: Prover uma interface simplificada para a utilização de várias interfaces de um subsis-
tema.
Considere uma pessoa planejando suas próximas férias de verão. Ela poderia comprar a passa-gem aérea, reservar o hotel e agendar passeios, tudo por conta própria.
Entretanto, tudo isso poderia ser muito trabalhoso. Em particular, ela precisaria pesquisar pre-ços, comparar opções, reservar o hotel de acordo com as datas de chegada e saída de seu voo, etc.
É nesse ponto que entram as agências de viagens. Elas podem facilitar essa tarefa e trazer como-
didade àquele que deseja viajar, atuando como um intermediário entre o cliente e as companhiasaéreas, hotéis e empresas de passeio.
62 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 67/121
63 P ADRÕES ESTRUTURAIS
Figura 3.9: Pessoa comprando um pacote oferecido por uma agência de viagens
A ideia do padrão Facade é a mesma da agência de viagens, ou seja, simplificar a interação de umcliente com diversos sistemas.
Exemplo prático
Estamos melhorando um sistema que realiza todos os procedimentos que devem ser realizadosapós o registro de um pedido. Quando um pedido é realizado, o módulo que gerencia o estoque deveser avisado para que o produto seja encaminhado ao endereço de entrega. O módulo financeiro deveser avisado para que o processo de faturamento seja realizado. O módulo de pós venda tambémdeve ser avisado para que contatos futuros sejam realizados com o cliente com o intuito de verificara satisfação do mesmo com o produto obtido.
O sistema já está funcionando e realiza todos os processos decorrentes da realização de um novopedido. Mas, queremos simplificar essa lógica encapsulando as chamadas aos módulos de estoque,financeiro e de pós venda.
1 Pedido p = ...
2 e s t oq u e . e n v i aP r o d ut o ( p . g e t P r od u t o ( ) , p . g e t E n d er e c o De E n t r eg a ( ) , p . g e t N o t a Fi s c a l ( ) ) ;
3 f i n ac e i r o . f a tu r a ( p . g e tC l i e nt e ( ) , p . g e t N o ta F i s ca l ( ) ) ;
4 p o s Ve n d a . a g e nd a C o nt a t o ( p . g e t Cl i e n te ( ) , p . g e t P r od u t o ( ) ) ;
Código Java 3.47: disparando os processos decorrentes de um novo pedido
A ideia aqui é criar uma classe que encapsula todos os processos que envolvem o acesso aosmódulos de estoque, financeiro e de pós venda.
www.k19.com.br 63
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 68/121
P ADRÕES ESTRUTURAIS 64
1 p u b li c c l a ss P e d i do F a c ad e {
2 private E s t oq u e e s t oq u e ;
3
4 private Financeiro financeiro;
56 private P o s V en d a p o s Ve n d a ;
7
8 public P e d i do F a c ad e ( E s t o q ue e s to q ue , F i n a nc e i ro f i n an c e ir o , P o s V en d a p o s Ve n d a ) {
9 this . e s t o qu e = e s t oq u e ;
1 this . f i n a n ce i r o = f i n a nc e i r o ;
11 this . p o s V en d a = p o s Ve n d a ;
12 }
13
14 p u b li c v o id r e g i st r a P ed i d o ( P e d id o p ) {
15 this . e s t o qu e . e n v i a Pr o d u to ( p . g e t P r od u t o ( ) , p . g e t E n d er e c o De E n t r eg a ( ) , p .←
getNotaFiscal());
16 this .financeiro.fatura(p. getCliente(), p.getNotaFiscal());
17 this .posVenda.agendaContato( p.getCliente(), p.getProduto());
18 }
19
2 p u b li c v o id c a n c el a P e di d o ( P e d id o p ) {21 / / l o g ic a p a ra c a n ce l a r p e d id o s
22 }
23 }
Código Java 3.48: PedidoFacade.java
Agora, quando um pedido é realizado, não é mais necessário acessar diretamente diversos mó-dulos diferentes, diminuindo assim a complexidade das operações.
1 Pedido p = ...
2 P e di d oF a ca d e p ed i do F ac a de = . . .
3 p e d i do F a c ad e . r e g i s t ra P e d id o ( p ) ;
Código Java 3.49: Registrando um pedido
Da mesma forma, se um pedido for cancelado, devemos acionar a fachada.
1 Pedido p = ...
2 P e di d oF a ca d e p ed i do F ac a de = . . .
3 p e d i do F a c ad e . c a n c e l aP e d i do ( p ) ;
Código Java 3.50: Cancelando um pedido
Organização
O diagrama UML abaixo ilustra a organização desse padrão.
Figura 3.10: UML do padrão Facade
64 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 69/121
65 P ADRÕES ESTRUTURAIS
Os personagens desse padrão são:
Facade (PedidoFacade) Classe intermediária que simplifica o acesso aos Component.
ClientClasse que usa os Component de forma indireta através do Facade.
Component (Estoque, Financeiro, PosVenda)Classes que compõem o subsistema.
Exercícios de Fixação
27 Crie um projeto chamado Facade.
28 Defina as classes Pedido, Estoque, Financeiro e PosVenda .
1 p u b li c c l a ss P e d id o {
2 private S t r in g p r o du t o ;
3 private S t r in g c l i en t e ;
4 private S t r in g e n d e r ec o D e En t r e g a ;
5
6 public P e d id o ( S t r in g p r od u to , S t r in g c l ie n te , S t r in g e n d e r ec o D e En t r e g a ) {
7 this . p r o d ut o = p r o du t o ;
8 this . c l i e nt e = c l i en t e ;
9 this . e n d e r e co D e E n tr e g a = e n d e re c o D e En t r e ga ;
1 }
11
12 public S t r in g g e t P ro d u t o ( ) {13 return produto;
14 }
15
16 public S t r in g g e t C li e n t e ( ) {
17 return cliente;
18 }
19
2 public S t r in g g e t E n de r e c o De E n t re g a ( ) {
21 return enderecoDeEntrega;
22 }
23
24 }
Código Java 3.51: Pedido.java
1 import java.text.SimpleDateFormat;
2 import java.util.Calendar;
3
4 p u b li c c l a ss E s t oq u e {
5 p u b li c v o id e n v i aP r o d ut o ( S t r i ng p r od u to , S t r in g e n d e r ec o D e E nt r e g a ) {
6 Ca le nd ar ca le nd ar = C al en da r. ge tIn st an ce () ;
7 calendar .add (Calendar .DATE , 2) ;
8 SimpleDateFormat simpleDateFormat = ne w SimpleDateFormat( "dd/MM/yyyy" );
9 S tr in g f or ma t = s im pl eD at eF or ma t .f or ma t( ca le nd ar . ge tT im e () );
1
11 System . out . println ( " O p r od u to " + p r o du t o
12 + " s er á e n tr e gu e n o e n de r eç o " + e n d e re c o D e En t r e g a
13 + " a té as 18 h d o di a " + f o r ma t ) ;
14 }
15 }
Código Java 3.52: Estoque.java
www.k19.com.br 65
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 70/121
P ADRÕES ESTRUTURAIS 66
1 p u b li c c l a ss F i n a nc e i r o {
2 p u b li c v o id f a t ur a ( S t r in g c l ie n te , S t r in g p r o du t o ) {
3 System . out . println ( "Fatura:" );
4 System . out . println ( " C l i e nt e : " + c l i en t e ) ;
5 System . out . println ( " P r o d ut o : " + p r o du t o ) ;6 }
7 }
Código Java 3.53: Financeiro.java
1 p u b li c c l a ss P o s Ve n d a {
2 p u b li c v o id a g e n da C o n ta t o ( S t r in g c l ie n te , S t r in g p r o du t o ) {
3 Ca le nd ar ca le nd ar = C al en da r. ge tIn st an ce () ;
4 calendar .add (Calendar .DATE , 3) ;
5 SimpleDateFormat simpleDateFormat = ne w SimpleDateFormat( "dd/MM/yyyy" );
6 S tr in g f or ma t = s im pl eD at eF or ma t .f or ma t( ca le nd ar . ge tT im e () );
7
8 System . out . println ( " E n tr a r e m c o nt a to c om " + c l i en t e
9 + " s ob re o p ro du to " + p r od u to + " n o d i a " + f o r ma t ) ;
1 }11 }
Código Java 3.54: PosVenda.java
29 Crie uma classe PedidoFacade que encapsula o acesso aos módulos de estoque, financeiro epós venda.
1 p u b li c c l a ss P e d i do F a c ad e {
2 private E s t oq u e e s t oq u e ;
3 private Financeiro financeiro;
4 private P o s V en d a p o s Ve n d a ;
5
6 public P e d i do F a c ad e ( E s t o q ue e s to q ue , F i n a nc e i ro f i n an c e ir o , P o s V en d a p o s Ve n d a ) {7 this . e s t o qu e = e s t oq u e ;
8 this . f i n a n ce i r o = f i n a nc e i r o ;
9 this . p o s V en d a = p o s Ve n d a ;
1 }
11
12 p u b li c v o id r e g i st r a P ed i d o ( P e d id o p ) {
13 this . e s t o qu e . e n v i a Pr o d u to ( p . g e t P r od u t o ( ) , p . g e t E n d er e c o De E n t r eg a ( ) , p .←
getNotaFiscal());
14 this .financeiro.fatura(p. getCliente(), p.getNotaFiscal());
15 this .posVenda.agendaContato( p.getCliente(), p.getProduto());
16 }
17 }
Código Java 3.55: PedidoFacade.java
30 Teste a classe PedidoFacade.
1 p u b li c c l a ss T e s t e Pe d i d o Fa c a d e {
2 p u b li c s t a ti c v o id m a i n ( S tr i n g [] a r gs ) {
3 Estoque estoque = ne w Estoque();
4 Financeiro financeiro = ne w Financeiro();
5 PosVenda posVenda = ne w PosVenda();
6 PedidoFacade facade = ne w PedidoFacade(estoque , financeiro , posVenda);
7 Pedido pedido = ne w Pedido("Notebook" , " R a f a el C o s e nt i n o ",
8 " A v B r ig a de i ro F ar ia L im a , 1 57 1 , S ão P au lo , S P ");
9 facade .registraPedido (pedido );
1 }
11 }
Código Java 3.56: TestePedidoFacade.java
66 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 71/121
67 P ADRÕES ESTRUTURAIS
Front Controller (não GoF)
Objetivo: Centralizar todas as requisições a uma aplicação Web.
Exemplo prático
Estamos desenvolvendo um framework MVC para o desenvolvimento de aplicações webem Java.
O processamento de uma requisição HTTP segue os seguintes passos:
• Converter os dados enviados pelo navegador para os tipos de Java.
• Validar os valores convertidos.
• Acionar o processamento das regras de negócio.
• Acionar a montagem da tela de resposta.
• Enviar a tela para o usuário.
O nosso framework deve interceptar todas as requisições HTTP para realizar esses passos. Parainterceptar as requisições HTTP, podemos implementar uma Servlet.
1 @ We bS er vl et ("/*" )
2 p u b li c c l a ss FrontController extends H t t p Se r v l et {3 p u b li c v o id s e r vi c e ( H t t p S er v l e t Re q u e st r eq , H t t p S er v l e tR e s p o ns e r e s ) {
4 / / p a s so 1
5 / / p a s so 2
6 / / p a s so 3
7 / / p a s so 4
8 }
9 }
Código Java 3.57: FrontController.java
As tarefas que devem ser realizadas em todas as requisições podem ser implementadas nessa
Servlet. Por outro lado, as tarefas específicas devem ser delegadas para outra parte do framework oupara a aplicação.
www.k19.com.br 67
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 72/121
P ADRÕES ESTRUTURAIS 68
Figura 3.11: Front Controller
Exercícios de Fixação
31 Crie um projeto web chamado FrontController.
32 Configure um web container através da view servers e implante o projeto FrontController no web container configurado.
33 Adicione a seguinte implementação do FrontController no nosso framework.
1 package controllers;
2
3 import java.io.IOException;
4 import java.lang.reflect.Method;
5
6 import javax.servlet.RequestDispatcher;
7 import javax.servlet.ServletException;
8 import javax.servlet.annotation.WebServlet;
9 import javax.servlet.http.HttpServlet;
1 import javax.servlet.http.HttpServletRequest;11 import javax.servlet.http.HttpServletResponse;
12
13 @ W eb S er v le t ("*.k19" )
14 p u b li c c l a ss FrontController extends H t t p Se r v l et {
15 p r i va t e s t a ti c f i na l l o ng s e r i al V e r s io n U I D = 1 L ;
16
17 p u b li c v o id s e r vi c e ( H t t p S er v l e t Re q u e st r eq , H t t p S er v l e tR e s p o ns e r e s )
18 throws ServletException , IOException {
19 S tri ng [] s plit = req . ge tR equ es tUR I() .spli t("/ ");
2
21 String controllerName = split [2];
22 String actionName = split [3]. split ("\\." )[];
23
24 S yst em .out .pr in tl n( co nt ro ll erN am e) ;
25 System .out .println (actionName );
2627 tr y {
28
68 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 73/121
69 P ADRÕES ESTRUTURAIS
29 Class <? > controllerClass = Class .forName ("controllers."
3 + controllerName );
31 M eth od me tho d = c on tr oll er Cl ass . ge tD ec la re dM et ho d( act io nN ame );
32
33 Object controller = controllerClass .newInstance () ;
34 method . invoke ( controller );35
36 R equ es tD is pa tc he r di spa tc he r = req . ge tR eq ues tD is pa tc he r("/ " + ←
controllerName
37 + " /" + a c ti o nN a me + ".jsp" );
38
39 dispatcher . forward ( req , res ) ;
4 } catch ( E x ce p ti o n e ) {
41 e. printStackTrace () ;
42 }
43 }
44 }
Código Java 3.58: FrontController.java
34 Adicione um controlador nos padrões do nosso framework.
1 package controllers;
2
3 p u b li c c l a ss T e st e {
4 p u b li c v o id teste(){
5 System . out . println ( "Teste.teste()" );
6 }
7 }
Código Java 3.59: Teste.java
35 Adicione a pasta Teste que contém o arquivo teste.jsp na pasta WebContent.
1 < html >
2 < head >
3 < title >Teste - teste </ title >
4 </ head >
5 < body >
6 < h1 >co nt ro ll er : Tes te </ h1 >
7 < h1 >action: teste </ h1 >
8 </ body >
9 < /html >
Código 3.1: teste.jsp
36 Inicialize o web container e acesse a página:
http://localhost:88/FrontController/Teste/teste.k19
Flyweight
Objetivo: Compartilhar, de forma eficiente, objetos que são usados em grande quantidade.
Exemplo prático
Estamos desenvolvendo uma aplicação para gerenciar milhares de apresentações com slides.Essa aplicação disponibilizará um conjunto de temas que podem ser aplicados individualmente em
www.k19.com.br 69
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 74/121
P ADRÕES ESTRUTURAIS 70
cada slide de uma apresentação.
Em geral, o conteúdo (título e texto) de cada slide é único. Portanto, não seria possível comparti-lhar de maneira eficiente o conteúdo de slides diferentes.
Por outro lado, como vários slides podem utilizar o mesmo tema, eles poderiam compartilharas informações relativas à formatação da fonte, cor de fundo, layout, e etc. Consequentemente, aquantidade de memória utilizada seria drasticamente reduzida.
Figura 3.12: O mesmo tema sendo aplicado a diferentes slides
Podemos definir uma interface para padronizar o funcionamento dos temas.
1 public interface T e m a Fl y w e ig h t {
2 void i m p ri m e ( S t r in g t i tu l o , S t r in g t e x to ) ;
3 }
Código Java 3.60: TemaFlyweight.java
A interface TemaFlyweight define um método que recebe o conteúdo dos slides e deve aplicar a
formatação correspondente ao tema. Com a interface definida, podemos implementar alguns temasespecíficos.
1 p u b li c c l a ss TemaHifen implements T e m a Fl y w e ig h t {
2 p u b li c v o id i m p ri m e ( S t r in g t i tu l o , S t r in g t e x to ) {
3 / / i m p l em e n t aç ã o
4 }
5 }
Código Java 3.61: TemaHifen.java
1 p u b li c c l a ss TemaAsterisco implements T e m a Fl y w e ig h t {
2 p u b li c v o id i m p ri m e ( S t r in g t i tu l o , S t r in g t e x to ) {
3 / / i m p l em e n t aç ã o
4 }
5 }
Código Java 3.62: TemaAsterisco.java
70 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 75/121
71 P ADRÕES ESTRUTURAIS
1 p u b li c c l a ss TemaK19 implements T e m a Fl y w e ig h t {
2 p u b li c v o id i m p ri m e ( S t r in g t i tu l o , S t r in g t e x to ) {
3 / / i m p l em e n t aç ã o
4 }
5 }
Código Java 3.63: TemaK19.java
Para controlar a criação e acesso dos objetos que definem os temas, podemos implementar aseguinte classe.
1 p u b li c c l a ss T e m a F ly w e i gh t F a c to r y {
2 p r i va t e s t a ti c Map< Class <? extends TemaFlyweight >, TemaFlyweight > temas = ne w ←
HashMap <Class <? extends TemaFlyweight >, TemaFlyweight >();
3 p u b li c s t a ti c f i n al Class <TemaAsterisco > ASTERISCO = TemaAsterisco. class ;
4 p u b li c s t a ti c f i n al C l as s < T e m a Hi f en > H I F EN = T e m a Hi f e n .class ;
5 p u b li c s t a ti c f i n al C l as s < T e m aK 1 9 > K 1 9 = T e m aK 1 9 . class ;
67 p u b li c s t a ti c TemaFlyweight getTema(Class <? extends TemaFlyweight > clazz) {
8 if ( ! t e ma s . c o n t a in s K e y ( c la z z ) ) {
9 tr y {
1 temas . put ( clazz , clazz . newInstance () ) ;
11 } catch ( E x ce p ti o n e ) {
12 e. printStackTrace () ;
13 }
14 }
15 return temas.get(clazz);
16 }
17 }
Código Java 3.64: TemaFlyweightFactory.java
Por fim, deveríamos associar os slides aos temas. Isso poderia ser feito através do construtor daclasse que define os slides.
1 p u b li c c l a ss S l id e {
2 private T e m a Fl y w e ig h t t e ma ;
3
4 public S l i de ( T e m a F l yw e i g ht t e ma ) {
5 this . t em a = t em a ;
6 }
7 }
Código Java 3.65: Slide.java
1 T e m a Fl y w e ig h t t e m a = T e m a F l y we i g h t Fa c t o r y . g e tT e m a ( T e m aF l y w e ig h t F a ct o r y . K 1 9 ) ;
2 S lide s lid e = ne w Slide(tema);
Código Java 3.66: Slide.java
Organização
O diagrama UML abaixo ilustra a organização desse padrão.
www.k19.com.br 71
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 76/121
P ADRÕES ESTRUTURAIS 72
Figura 3.13: UML do padrão Flyweight
Os personagens desse padrão são:
Flyweight (TemaFlyweight)Interface que define os objetos que serão compartilhados.
ConcreteFlyweight (TemaHifen, TemaAsterisco, TemaK19)Tipo específico de Flyweight.
FlyweightFactory (TemaFlyweightFactory)Classe que controla a criação e recuperação de Flyweights.
Client
UtilizaFlyweightFactory
para recuperar osFlyweights
.
Exercícios de Fixação
37 Crie um projeto chamado Flyweight.
38 Defina a interface TemaFlyweight.
1 public interface T e m a Fl y w e ig h t {
2 void i m p ri m e ( S t r in g t i tu l o , S t r in g t e x to ) ;
3 }
Código Java 3.67: TemaFlyweight.java
39 Agora, implemente alguns temas.
1 p u b li c c l a ss TemaHifen implements T e m a Fl y w e ig h t {
2 p u b li c v o id i m p ri m e ( S t r in g t i tu l o , S t r in g t e x to ) {
3 System . out . println ( " - - - - - - -- - - " + t it ul o + " - - - - -- - - - - ") ;
4 System .out . println (texto );
5 char [ ] r o da p e = n e w c h ar [ 2 2 + t i t ul o . l e n gt h ( ) ] ;
6 Arrays . fill ( rodape , ’- ’) ;
7 System .out . println (rodape );
8 }
9 }
Código Java 3.68: TemaHifen.java
72 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 77/121
73 P ADRÕES ESTRUTURAIS
1 p u b li c c l a ss TemaAsterisco implements T e m a Fl y w e ig h t {
2 p u b li c v o id i m p ri m e ( S t r in g t i tu l o , S t r in g t e x to ) {
3 System . out . println ( " * * * * * ** * * * " + t it ul o + " * * * * ** * * ** " ) ;
4 System .out . println (texto );
5 char [ ] r o da p e = n e w c h ar [ 2 2 + t i t ul o . l e n gt h ( ) ] ;6 Arrays . fill ( rodape , ’* ’) ;
7 System .out . println (rodape );
8 }
9 }
Código Java 3.69: TemaAsterisco.java
1 p u b li c c l a ss TemaK19 implements T e m a Fl y w e ig h t {
2 p u b li c v o id i m p ri m e ( S t r in g t i tu l o , S t r in g t e x to ) {
3 System . out
4 . println (" # # # # # ## # # # " + t i t ul o . t o U p p er C a s e ( ) + " # # # # ## # # # # ");
5 System .out . println (texto );
6 char [ ] r o da p eE = n e w c h ar [( in t ) M a th . f l o o r ( (6 + t i t ul o . l e n g th ( ) ) / 2 . ) ];
7 char [ ] r o da p eD = n e w c h ar [( in t ) M a th . c e i l ( ( 6 + t i t ul o . l e n gt h ( ) ) / 2 . ) ] ;
8 Arrays . fill ( rodapeE , ’# ’);
9 Arrays . fill ( rodapeD , ’# ’);
1 System . out . println ( ne w S t r in g ( r o d a pe E ) + " w w w . k1 9 . c o m . br "
11 + ne w String(rodapeD));
12 }
13 }
Código Java 3.70: TemaK19.java
40 Defina uma classe para controlar a criação e recuperação dos temas.
1 p u b li c c l a ss T e m a F ly w e i gh t F a c to r y {
2 p r i va t e s t a ti c Map< Class <? extends TemaFlyweight >, TemaFlyweight > temas = ne w ←
HashMap <Class <? extends TemaFlyweight >, TemaFlyweight >();
3 p u b li c s t a ti c f i n al Class <TemaAsterisco > ASTERISCO = TemaAsterisco. class ;
4 p u b li c s t a ti c f i n al C l as s < T e m a Hi f en > H I F EN = T e m a Hi f e n .class ;5 p u b li c s t a ti c f i n al C l as s < T e m aK 1 9 > K 1 9 = T e m aK 1 9 . class ;
6
7 p u b li c s t a ti c TemaFlyweight getTema(Class <? extends TemaFlyweight > clazz) {
8 if ( ! t e ma s . c o n t a in s K e y ( c la z z ) ) {
9 tr y {
1 temas . put ( clazz , clazz . newInstance () ) ;
11 } catch ( E x ce p ti o n e ) {
12 e. printStackTrace () ;
13 }
14 }
15 return temas.get(clazz);
16 }
17 }
Código Java 3.71: TemaFlyweightFactory.java
41 Defina uma classe para representar um slide.
1 p u b li c c l a ss S l id e {
2 private T e m a Fl y w e ig h t t e ma ;
3 private S t r in g t i t ul o ;
4 private S t r in g t e xt o ;
5
6 public S l i de ( T e m a F l yw e i g ht t em a , S t r in g t i tu l o , S t r in g t e x to ) {
7 this . t em a = t em a ;
8 this . t i t u lo = t i t ul o ;
9 this . t e xt o = t e xt o ;
1 }
11
12 p u b li c v o id i m p ri m e ( ) {13 this .tema.imprime(titulo , texto);
14 }
www.k19.com.br 73
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 78/121
P ADRÕES ESTRUTURAIS 74
15 }
Código Java 3.72: Slide.java
42 Crie uma classe para modelar uma apresentação.
1 p u b li c c l a ss A p r e se n t a ca o {
2 private L i st < S l i d e > s l i de s = ne w ArrayList <Slide >();
3
4 p u b li c v o id a d i c io n a S li d e ( S l i de s l id e ) {
5 slides . add ( slide );
6 }
7
8 p u b li c v o id i m p ri m e ( ) {
9 fo r ( S l id e s li d e : this . s l id e s ) {
1 slide . imprime () ;
11 System . out . println () ;
12 }
13 }
14 }
Código Java 3.73: Apresentacao.java
43 Teste a utilização dos temas.
1 p u b li c c l a ss T e s t aT e m a s {
2 p u b li c s t a ti c v o id m a i n ( S tr i n g [] a r gs ) {
3 Apresentacao a = ne w Apresentacao();
4 a. adicionaSlide ( ne w Slide(TemaFlyweightFactory
5 . getTema ( TemaFlyweightFactory . K19 ) ,
6 " K 11 - O r ie n ta ç ão a O b je t os e m J av a ",
7 " C om e st e c u rs o v oc ê v ai o bt e r u ma b as e \ n"
8 + " s ó l i da d e c o n h ec i m e nt o s d e J a va \ n "
9 + " e d e O r ie n ta ç ão a O b je t os . ")) ;1 a. adicionaSlide ( ne w Slide(TemaFlyweightFactory
11 . getTema (TemaFlyweightFactory .ASTERISCO ),
12 " K 12 - D e se n vo l vi m en t o W eb c om J SF 2 e J PA 2 ",
13 " D e po is d es t e c ur so , v oc ê e s ta r á a pt o a \ n"
14 + " d e s e n vo l v e r a p l i ca ç õ e s W e b c o m \ n "
15 + " o s p a d rõ e s d a p l a t af o r ma J a va . " )) ;
16 a. adicionaSlide ( ne w Slide(TemaFlyweightFactory
17 . getTema ( TemaFlyweightFactory . HIFEN ) ,
18 " K 21 - P e rs i st ê nc i a c om J PA 2 e H i be r na t e ",
19 " N e s te c u rs o d e J a va A v an ç ad o , a b o rd a m o s d e \ n "
2 + " m a n e ir a p r o fu n d a o s r e c ur s o s d e p e r s is t ê n ci a \ n "
21 + " d o J PA 2 e d o H i be r na t e .")) ;
22
23 a. imprime () ;
24 }
25 }
Código Java 3.74: TestaTemas.java
Proxy
Objetivo: Controlar as chamadas a um objeto através de outro objeto de mesma interface.
Se uma queda de energia ocorrer enquanto estamos desenvolvendo um trabalho no computa-dor, este trabalho pode ser perdido. Para evitar situações como essa, podemos utilizar um no-break .
Após uma interrupção no fornecimento de energia, este aparelho mantém o computador ligado portempo suficiente para que possamos salvar o nosso trabalho.
74 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 79/121
75 P ADRÕES ESTRUTURAIS
Para isso, o computador deve estar conectado ao no-break e não à tomada. O no-break , por suavez, deve estar conectado à tomada.
Não queremos alterar o plugue do computador, portanto é interessante que o no-break possua o
mesmo encaixe que a tomada.
Figura 3.14: Computador conectado ao no-break
Essa é a mesma ideia do padrão Proxy. Esse padrão define um intermediário para controlar oacesso a um determinado objeto, podendo adicionar funcionalidades que esse objeto não possui.
Exemplo prático
Estamos desenvolvendo uma aplicação bancária que deve registrar todas as operações realiza-
das pelos objetos que representam as contas do banco. O registro das operações pode ser utilizadoposteriormente em uma auditoria.
Para manter o sistema mais coeso, não queremos implementar o registro das operações dentrodos objetos que representam as contas. A ideia é implementar essa lógica em objetos intermediá-rios. Para preservar o modo de utilização das contas, podemos manter a interface nesses objetosintermediários.
Podemos definir uma interface para padronizar os métodos dos objetos que representam as con-tas e os objetos intermediários responsáveis pelo registro das operações.
1 public interface C o nt a {
2 void deposita( double valor);
3 void saca( double valor);
4 double getSaldo();
5 }
Código Java 3.75: Conta.java
Podemos implementar vários tipos específicos de contas. Por exemplo:
1 p u b li c c l a ss ContaPadrao implements C on t a {
2 p r i va t e d o u bl e saldo;
3
4 p u b li c v o id deposita( double v al o r ) {
5 this . s a ld o + = v a lo r ;
6 }
78 p u b li c v o id saca( double v al o r ) {
9 this . s a ld o - = v a lo r ;
www.k19.com.br 75
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 80/121
P ADRÕES ESTRUTURAIS 76
1 }
11
12 p u b li c d o u bl e g e t Sa l d o ( ) {
13 r e t ur n t h is .saldo;
14 }
15 }
Código Java 3.76: ContaPadrao.java
Implementando a mesma interface das contas, podemos definir os objetos intermediários.
1 p u b li c c l a ss ContaProxy implements C o nt a {
2 private C o n ta c o n ta ;
3
4 public C o n t aP r o xy ( C o n t a c o n ta ) {
5 this . c o nt a = c o nt a ;
6 }
7
8 p u b li c v o id deposita( double v al o r ) {
9 / / r e g is t r a a o p e ra ç ã o1 this .conta.depostia(valor);
11 }
12
13 p u b li c v o id saca( double v al o r ) {
14 / / r e g is t r a a o p e ra ç ã o
15 this .conta.saca(valor);
16 }
17
18 p u b li c d o u bl e g e t Sa l d o ( ) {
19 / / r e g is t r a a o p e ra ç ã o
2 r e t ur n t h is .conta.getSaldo();
21 }
22 }
Código Java 3.77: ContaProxy.java
Organização
O diagrama UML abaixo ilustra a organização desse padrão.
Figura 3.15: UML do padrão Proxy
Os personagens desse padrão são:
Subject (Conta)Interface que padroniza RealSubject e Proxy.
76 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 81/121
77 P ADRÕES ESTRUTURAIS
RealSubject (ContaPadrão)Define um tipo de objeto do domínio da aplicação.
Proxy (ContaProxy)
Define os objetos que controlam o acesso aos RealSubjects.
ClientCliente que usa o RealSubject por meio do Proxy.
Exercícios de Fixação
44 Crie um projeto chamado Proxy .
45 Crie uma interface Conta .
1 public interface C o nt a {
2 void deposita( double valor);
3 void saca( double valor);
4 double getSaldo();
5 }
Código Java 3.78: Conta.java
46 Defina a classe ContaPadrao que implementa a interface Conta .
1 p u b li c c l a ss ContaPadrao implements C on t a {
2 p r i va t e d o u bl e saldo;
34 p u b li c v o id deposita( double v al o r ) {
5 this . s a ld o + = v a lo r ;
6 }
7
8 p u b li c v o id saca( double v al o r ) {
9 this . s a ld o - = v a lo r ;
1 }
11
12 p u b li c d o u bl e g e t Sa l d o ( ) {
13 r e t ur n t h is .saldo;
14 }
15 }
Código Java 3.79: ContaPadrao.java
47 Crie uma classe intermediária ContaProxy que fará os registros das operações.
1 p u b li c c l a ss ContaProxy implements Conta{
2 private C o n ta c o n ta ;
3 public C o n t aP r o xy ( C o n t a c o n ta ) {
4 this . c o nt a = c o nt a ;
5 }
6
7 p u b li c v o id deposita( double v al o r ) {
8 System . out . println ( " E f et u an d o o d e pó s it o d e R $ "+valor+ "..." );
9 this .conta.deposita(valor);
1 System . out . println ( " D e pó s it o d e R $ "+valor+ " e f e tu a d o . .. " ) ;
11 }
12
13 p u b li c v o id saca( double v al o r ) {14 System . out . println ( " E f et u an d o o s aq ue d e R $ " +valor);
15 this .conta.saca(valor);
www.k19.com.br 77
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 82/121
P ADRÕES ESTRUTURAIS 78
16 System . out . println ( " S aq ue d e R $ "+valor+ " e f e t ua d o . ") ;
17
18 }
19
2 p u b li c d o u bl e g e t Sa l d o ( ) {
21 System . out . println ( " V e r i f ic a n d o o s a l do . . . ");22 r e t ur n t h is .conta.getSaldo();
23 }
24 }
Código Java 3.80: ContaProxy.java
48 Teste a classe ContaProxy .
1 p u b li c c l a ss T e s t eP r o x y {
2 p u b li c s t a ti c v o id m a i n ( S tr i n g [] a r gs ) {
3 Conta contaPadrao = ne w ContaPadrao();
4 Conta contaProxy = ne w ContaProxy(contaPadrao);
5 contaProxy .deposita (1) ;
6 contaProxy . saca (59) ;7 System . out . println ( " S al d o : " + c o n t aP r o x y . g e tS a l do ( ) ) ;
8 }
9 }
Código Java 3.81: TesteProxy.java
78 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 83/121
P ADRÕES COMPORTAMENTAIS
C A P
Í T U
L O
4 Veja abaixo um resumo do objetivo de cada padrão comportamental.
Command Controlar as chamadas a um determinado componente, modelando cada requisiçãocomo um objeto. Permitir que as operações possam ser desfeitas, enfileiradas ou registradas.
Iterator Fornecer um modo eficiente para percorrer sequencialmente os elementos de uma coleção,
sem que a estrutura interna da coleção seja exposta.Mediator Diminuir a quantidade de “ligações” entre objetos introduzindo um mediador, através do
qual toda comunicação entre os objetos será realizada.
Observer Definir um mecanismo eficiente para reagir às alterações realizadas em determinados ob- jetos.
State Alterar o comportamento de um determinado objeto de acordo com o estado no qual ele seencontra.
Strategy Permitir de maneira simples a variação dos algoritmos utilizados na resolução de um de-terminado problema.
Template Method Definir a ordem na qual determinados passos devem ser realizados na resoluçãode um problema e permitir que esses passos possam ser realizados de formas diferentes deacordo com a situação.
Visitor Permitir atualizações específicas em uma coleção de objetos de acordo com o tipo particularde cada objeto atualizado.
Command
Objetivo: Controlar as chamadas a um determinado componente, modelando cada requisição
como um objeto. Permitir que as operações possam ser desfeitas, enfileiradas ou registradas.
Exemplo prático
Estamos desenvolvendo um aplicativo para gerenciar playlists de música. Os usuários poderãoselecionar as suas músicas favoritas e definir a ordem na qual elas devem ser reproduzidas. Umplaylist é basicamente uma sequência de músicas. Contudo, o aplicativo pode adicionar, entre asmúsicas de um playlist, comandos para aumentar ou diminuir o volume de reprodução.
Vamos utilizar uma biblioteca de áudio para desenvolver esse aplicativo. Através dessa biblio-teca, podemos tocar músicas e controlar o volume das saídas de áudio.
www.k19.com.br 79
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 84/121
P ADRÕES COMPORTAMENTAIS 80
1 p u b li c c l a ss P l a ye r {
2 p u b li c v o id p l ay ( F i l e f i l e ) {
3 / / i m p l em e n t aç ã o
4 }
56 p u b li c v o id increaseVolume( in t l e v el s ) {
7 / / i m p l em e n t aç ã o
8 }
9
1 p u b li c v o id decreaseVolume( in t l e v el s ) {
11 / / i m p l em e n t aç ã o
12 }
13 }
Código Java 4.1: Player.java (classe da biblioteca)
Os três métodos da classe Player são “bloqueantes”. Por exemplo, o método play() só terminaquando a música que está sendo reproduzida terminar.
Devemos controlar os comandos enviados ao player da biblioteca para poder implementar onosso aplicativo. Vamos definir uma interface para padronizar os comandos e criar classes paramodelar os comandos.
1 public interface C o m an d o {
2 void executa();
3 }
Código Java 4.2: Comando.java
1 p u b li c c l a ss TocaMusicaComando implements C o m an d o {
2 private P l a ye r p l a ye r ;
3 private F i le f i le ;
45 public T o c a Mu s i c a Co m a n d o ( P l ay e r p l ay e r , F i le f i l e ) {
6 this . p l a y er = p l a ye r ;
7 this . f il e = f il e ;
8 }
9
1 p u b li c v o id e x e cu t a ( ) {
11 this .player.play( this .file);
12 }
13 }
Código Java 4.3: TocaMusicaComando.java
1 p u b li c c l a ss AumentaVolumeComando implements C o m an d o {
2 private P l a ye r p l a ye r ;
3 p r i va t e i n t levels;4
5 public AumentaVolumeComando(Player player , in t l e v el s ) {
6 this . p l a y er = p l a ye r ;
7 this . l e v e ls = l e v el s ;
8 }
9
1 p u b li c v o id e x e cu t a ( ) {
11 this .player.increaseVolume( this .levels);
12 }
13 }
Código Java 4.4: AumentaVolumeComando.java
1 p u b li c c l a ss DiminuiVolumeComando implements C o m an d o {
2 private P l a ye r p l a ye r ;3 p r i va t e i n t levels;
4
80 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 85/121
81 P ADRÕES COMPORTAMENTAIS
5 public DiminuiVolumeComando(Player player , in t l e v el s ) {
6 this . p l a y er = p l a ye r ;
7 this . l e v e ls = l e v el s ;
8 }
9
1 p u b li c v o id e x e cu t a ( ) {11 this .player.decreaseVolume( this .levels);
12 }
13 }
Código Java 4.5: DiminuiVolumeComando.java
Agora, devemos implementar uma classe que dispara os comandos na ordemdefinida pelo usuá-rio.
1 p u b li c c l a ss L i s t aD e C o ma n d o s {
2 private List<Comando > comandos = ne w ArrayList <Comando >();
34 p u b li c v o id a d i c io n a ( C o m an d o c o m an d o ) {
5 this .comandos.add(comando);
6 }
7
8 p u b li c v o id executa(){
9 fo r ( C o m a nd o c o m an d o : this . c o m a n do s ) {
1 comando . executa () ;
11 }
12 }
13 }
Código Java 4.6: ListaDeComandos.java
Por fim, teríamos que criar os comandos associados a um player e depois adicioná-los em umplaylist.
1 P la ye r pl ay er = ne w Player();
2 L i st a De C om a nd o s l i st a De C om a nd o s = ne w ListaDeComandos();
3
4 l i st a De C om a nd o s . a di c io n a (ne w TocaMusicaComando(player , ne w File("musica1.mp3" )));
5 l i st a De C om a nd o s . a di c io n a (ne w AumentaVolumeComando(player , 3));
6 l i st a De C om a nd o s . a di c io n a (ne w TocaMusicaComando(player , ne w File("musica2.mp3" )));
7 l i st a De C om a nd o s . a di c io n a (ne w DiminuiVolumeComando(player , 3));
8 l i st a De C om a nd o s . a di c io n a (ne w TocaMusicaComando(player , ne w File("musica3.mp3" )));
9
1 l i s t aD e C o m an d o s . e x e cu t a ( ) ;
Código Java 4.7: exemplo de uso
Organização
O diagrama UML abaixo ilustra a organização desse padrão.
www.k19.com.br 81
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 86/121
P ADRÕES COMPORTAMENTAIS 82
Figura 4.1: UML do padrão Command
Os personagens desse padrão são:
Command (Comando)Define uma interface para a execução dos métodos do Receiver.
ConcreteCommand (TocaMusicaComando, AumentaVolumeComando, DiminuiVolumeComando)Classe que implementa Command e modela uma operação específica do Receiver.
Invoker (ListaDeComandos)Classe que armazena os Commands que devem ser executados.
Receiver (Player)Define os objetos que terão as chamadas aos seus métodos controladas.
ClientInstancia os Commands associando-os ao Receiver e armazena-os no Invoker.
Exercícios de Fixação
1 Crie um projeto chamado Command.
2 Crie uma classe Player.
1 p u b li c c l a ss P l a ye r {
2 p u b li c v o id p l ay ( S t r i ng f i l en a m e ) throws I n t e r ru p t e d Ex c e p t io n {
3 System . out . println ( " T oc an do o a rq ui vo " +filename);
4 long d u ra c ao = ( long ) ( M a t h . r a nd o m ( ) * 2 ) ;
5 System . out . println ( " D u ra ç ão ( s ) : " + d u r ac a o / 1 . ) ;
6 Thread .sleep ( duracao );
7 System . out . println ( "Fim" );
8 }
9
1 p u b li c v o id increaseVolume( in t l e v el s ) {11 System . out . println ( " D i mi n ui n do o v o lu m e e m " + l e v el s ) ;
12 }
82 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 87/121
83 P ADRÕES COMPORTAMENTAIS
13
14 p u b li c v o id decreaseVolume( in t l e v el s ) {
15 System . out . println ( " A u me n ta n do o v o lu m e e m " + l e v el s ) ;
16 }
17 }
Código Java 4.8: Player.java
3 Defina uma interface para padronizar os comandos enviados ao player.
1 public interface C o m an d o {
2 void executa(Player player);
3 }
Código Java 4.9: Comando.java
4 Defina as classes que modelarão os comandos enviados ao player.
1 p u b li c c l a ss TocaMusicaComando implements C o m an d o {
2 private P l a ye r p l a ye r ;
3 private S t r in g f i le ;
4
5 public T o c a Mu s i c a Co m a n d o ( P l ay e r p l ay e r , S t r i ng f i le ) {
6 this . p l a y er = p l a ye r ;
7 this . f il e = f il e ;
8 }
9
1 p u b li c v o id e x e cu t a ( ) {
11 tr y {
12 this .player.play( this .file);
13 } catch ( I n t e r r u pt e d E xc e p t i on e ) {
14 e. printStackTrace () ;
15 }
16 }
17 }
Código Java 4.10: TocaMusicaComando.java
1 p u b li c c l a ss AumentaVolumeComando implements C o m an d o {
2 private P l a ye r p l a ye r ;
3 p r i va t e i n t levels;
4
5 public AumentaVolumeComando(Player player , in t l e v el s ) {
6 this . p l a y er = p l a ye r ;
7 this . l e v e ls = l e v el s ;
8 }
9
1 p u b li c v o id e x e cu t a ( ) {
11 this .player.increaseVolume( this .levels);
12 }13 }
Código Java 4.11: AumentaVolumeComando.java
1 p u b li c c l a ss DiminuiVolumeComando implements C o m an d o {
2 private P l a ye r p l a ye r ;
3 p r i va t e i n t levels;
4
5 public DiminuiVolumeComando(Player player , in t l e v el s ) {
6 this . p l a y er = p l a ye r ;
7 this . l e v e ls = l e v el s ;
8 }
9
1 p u b li c v o id e x e cu t a ( ) {
11 this .player.decreaseVolume( this .levels);12 }
13 }
www.k19.com.br 83
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 88/121
P ADRÕES COMPORTAMENTAIS 84
Código Java 4.12: DiminuiVolumeComando.java
5 Defina uma classe ListaDeComandos que conterá a lista de comandos na ordem definida pelousuário.
1 p u b li c c l a ss L i s t aD e C o ma n d o s {
2 private List<Comando > comandos = ne w ArrayList <Comando >();
3
4 p u b li c v o id a d i c io n a ( C o m an d o c o m an d o ) {
5 this .comandos.add(comando);
6 }
7
8 p u b li c v o id e x e cu t a ( ) {
9 fo r ( C o m a nd o c o m an d o : this . c o m a n do s ) {
1 comando . executa () ;
11 }12 }
13 }
Código Java 4.13: ListaDeComandos.java
6 Faça uma classe para testar a ListaDeComandos.
1 p u b li c c l a ss T e s t a Li s t a De C o m a nd o s {
2 p u b li c s t a ti c v o id m a i n ( S tr i n g [] a r gs ) {
3 Player player = ne w Player();
4 ListaDeComandos listaDeComandos = ne w ListaDeComandos();
5
6 listaDeComandos .adiciona (ne w TocaMusicaComando(player , "musica1.mp3" )) ;
7 listaDeComandos .adiciona (ne w AumentaVolumeComando(player , 3));
8 listaDeComandos .adiciona (ne w TocaMusicaComando(player , "musica2.mp3" )) ;
9 listaDeComandos .adiciona (ne w DiminuiVolumeComando(player , 3));
1 listaDeComandos .adiciona (ne w TocaMusicaComando(player , "musica3.mp3" )) ;
11
12 listaDeComandos .executa () ;
13 }
14 }
Código Java 4.14: TestaListaComandos.java
Iterator
Objetivo: Fornecer um modo eficiente para percorrer sequencialmente os elementos de uma cole-
ção, sem que a estrutura interna da coleção seja exposta.
Considere um turista que pretende visitar os principais pontos turísticos de determinada cidade.Infelizmente, ele não pôde planejar seus passeios e não sabe quais pontos turísticos existem nessacidade. Além disso, seu período de permanência na cidade é curto.
Para tornar sua experiência mais agradável, o turista pode solicitar o serviço de um guia turístico.
Guias conhecem muito bem a cidade onde atuam e sabem definir um bom roteiro para a visitaçãodos pontos turísticos.
84 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 89/121
85 P ADRÕES COMPORTAMENTAIS
Figura 4.2: Turista sendo auxiliado por um guia
A ideia do padrão Iterator é fornecer um meio eficiente de se percorrer todos os elementos de
www.k19.com.br 85
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 90/121
P ADRÕES COMPORTAMENTAIS 86
uma determinada coleção.
Exemplo prático
A maior parte das aplicações necessitam de estruturas de dados para organizar as informaçõesarmazenadas na memória. Cada estrutura estabelece um determinado conjunto de restrições relaci-onadas aos dados e disponibilizam operações eficientes para que possamos manipular as informa-ções.
Em geral, as plataformas de desenvolvimento de aplicações oferecem, através de bibliotecas, di-versas estruturas de dados para facilitar o trabalho dos programadores. Por exemplo, na plataformaJava, as classes ArrayList, LinkedList, Vector, HashSet e TreeSet são exemplos de implementa-ções disponíveis.
Muitas vezes, é necessário percorrer todos os elementos de uma estrutura de dados para realizaruma determinada tarefa. A organização interna de cada estrutura é complexa e deve estar encapsu-lada nas classes que as implementam. Dessa forma, em geral, o desenvolvedor não teria as condiçõesnecessárias para percorrer os elementos da estrutura de dados utilizada.
Podemos encapsular o processo de visitar cada elemento de uma estrutura de dados dentro delamesma. Essa abordagem é interessante pois cada estrutura conhece a sua organização interna po-dendo, dessa forma, implementar esse processo da maneira mais eficiente.
Na plataforma Java, as estruturasque possuem a capacidade de ter os seuselementos percorridosimplementam uma interface que abstrai a ideia desse processo.
1 public interface Iterable <E> {
2 Iterator <E > i ter at or () ;
3 }
Código Java 4.15: Iterable.java
Toda estrutura de dados que implementa a interface Iterable deve produzir objetos da interfaceIterator. Os objetos da interface Iterator funcionam como guias que indicam o melhor “caminho”para visitar os elementos de uma determinada estrutura.
1 I t er a to r < S t ri n g > g u ia = e s t r ut u r a . i t e ra t o r ( ) ;
2
3 while ( g u i a . h a sN e x t ( ) ) {4 S tr ing e le me nto = guia .next () ;
5 }
Código Java 4.16: Utilizando um Iterator
Do ponto de vista do programador, a complexidade para percorrer os elementos de uma estru-tura de dados está “escondida” dentro do iterator.
Organização
O diagrama UML abaixo ilustra a organização desse padrão.
86 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 91/121
87 P ADRÕES COMPORTAMENTAIS
Figura 4.3: UML do padrão Iterator
Os personagens desse padrão são:
Iterator (Iterator)Define a interface dos objetos que encapsulam toda a complexidade para percorrer os elemen-tos do Aggregate.
ConcreteIteratorImplementação da interface Iterator para um tipo específico de Aggregate.
Aggregate (Iterable)Define a interface das coleções de objetos que podem ter seus elementos percorridos atravésde um Iterator.
ConcreteAggregate (ArrayList, LinkedList, Vector, HashSet, TreeSet)Estrutura de dados que implementa o Aggregate.
Exercícios de Fixação
7 Crie um projeto chamado Iterator.
8 Defina uma classe ListaDeNomes que implementa a interface Iterable e mantém a lista de
nomes num array.1 p u b li c c l a ss ListaDeNomes implements Iterable <String > {
2 private S t r in g [ ] n o m es ;
3 p r i va t e i n t length;
4
5 public L i s t aD e N o me s ( S t r i ng [ ] n o m es ) {
6 this . n o me s = n o me s ;
7 this . l e n g th = this .nomes.length;
8 }
9
1 public Iterator <String > iterator() {
11 r e t ur n t h is . ne w ListaDeNomesIterator();
12 }
13
14 p r i va t e c l a ss ListaDeNomesIterator implements Iterator <String > {
15 p r i va t e i n t i = ;16
17 p u b li c b o o le a n h a s Ne x t ( ) {
www.k19.com.br 87
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 92/121
P ADRÕES COMPORTAMENTAIS 88
18 return ( this . i ) < L i s t aD e N o me s . this .length;
19 }
2
21 public S t ri n g n ex t ( ) {
22 return ListaDeNomes. this .nomes[i++];
23 }24
25 p u b li c v o id r e m ov e ( ) {
26 ListaDeNomes . this . n o m es [ i ] = null ;
27
28 fo r ( in t j = i ; ( j + 1 ) < L is ta De No me s .this . l e ng th ; j + +) {
29 ListaDeNomes . this . n o m es [ j ] = L i s t aD e N o me s . this . n om e s [j + 1 ];
3 }
31 ListaDeNomes . this .length --;
32 }
33 }
34 }
Código Java 4.17: ListaDeNomes.java
9 Teste a classe ListaDeNomes.
1 p u b li c c l a ss T e s t aI t e r at o r {
2 p u b li c s t a ti c v o id m a i n ( S tr i n g [] a r gs ) {
3 String [] nomes = ne w String[4];
4 nomes [] = " R a f a el C o s en t i n o ";
5 nomes [1] = " M a r c el o M a r ti n s ";
6 nomes [2] = " J o n as H i r at a ";
7 nomes [3] = " S o l a ng e D o m i ng u e s ";
8
9 ListaDeNomes listaDeNomes = ne w ListaDeNomes(nomes);
1 I te ra to r < St ri ng > i te ra to r = l is ta De No me s. i te ra to r () ;
11 iterator . hasNext () ;
12 iterator . remove () ;
13
14 while ( i t e r at o r . h a s Ne x t ( ) ) {
15 String nome = iterator . next () ;
16 System . out . println ( nome ) ;
17 }
18
19 System . out . println ( "-------------" );
2 System . out . println ( " T e s t an d o o f o r ea c h ");
21 fo r ( S t ri ng n om e : l i st a De N om e s ) {
22 System . out . println ( nome ) ;
23 }
24 }
25 }
Código Java 4.18: TestaIterator
Mediator
Objetivo: Diminuir a quantidade de “ligações” entre objetos introduzindo um mediador, através
do qual toda comunicação entre os objetos será realizada.
Considere a rede de telefonia fixa. Ela permite que ligações telefônicas sejam realizadas entrequaisquer dois aparelhos dessa rede. Obviamente, os aparelhos não estão diretamente conectadosentre si dois a dois. Tente imaginar a quantidade de fios que teria de estar conectada a cada aparelho.
Os telefones estão conectados a uma central que distribui as ligações de acordo com o númerodiscado, criando uma ligação temporária entre os dois aparelhos.
88 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 93/121
89 P ADRÕES COMPORTAMENTAIS
Figura 4.4: Rede de telefonia fixa com e sem uma central
A ideia do padrão Mediator é semelhante à ideia da central telefônica. Eliminar conexões exces-sivas entre elementos por meio da introdução de um intermediário único.
www.k19.com.br 89
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 94/121
P ADRÕES COMPORTAMENTAIS 90
Exemplo prático
Estamos desenvolvendo um sistema para controlar o fluxo de táxis e passageiros em um aero-
porto. Os táxis disponíveis ficam a espera de passageiros em uma fila organizada pela ordem dechegada. Da mesma forma, os passageiros que desejam utilizar um táxi ficam em uma fila de esperaque também é organizada pela ordem de chegada.
Criaremos umaclasse para modelar os passageiros, outra para os táxis e uma terceira para mediara comunicação entre esses objetos.
1 p u b li c c l a ss P a s s ag e i r o {
2 / / i m p l em e n t aç ã o
3 }
Código Java 4.19: Passageiro.java
1 p u b li c c l a ss T ax i {
2 / / i m p l em e n t aç ã o
3 }
Código Java 4.20: Taxi.java
1 p u b li c c l a ss C e n t ra l D e Ta x i {
2 / / i m p l em e n t aç ã o
3 }
Código Java 4.21: CentralDeTaxi.java
A central de táxi deve manter uma fila com os táxis disponíveis e outra com os passageiros emespera.
1 p u b li c c l a ss C e n t ra l D e Ta x i {
2 private L i st < T a x i > t a x i sL i v r es = ne w ArrayList <Taxi >();
3 private List<Passageiro > passageirosEmEspera = ne w ArrayList <Passageiro >();
4 }
Código Java 4.22: CentralDeTaxi.java
Além disso, a central de táxi deve disponibilizar um método que será acionado por um táxiquando esse fica disponível, e outro que será chamado por um passageiro quando esse entrar nafila de espera.
1 p u b li c c l a ss C e n t ra l D e Ta x i {
2 private L i st < T a x i > t a x i sL i v r es = ne w ArrayList <Taxi >();
3 private List<Passageiro > passageirosEmEspera = ne w ArrayList <Passageiro >();
4
5 p u b li c v o id a d i c i on a T a xi D i s p on i v e l ( T a xi t a xi ) {
6 / / i m p l em e n t aç ã o
7 }
8
9 p u b li c v o id p e d e Ta x i ( P a s s ag e i r o p a s s ag e i ro ) {
1 / / i m p l em e n t aç ã o
11 }
12 }
Código Java 4.23: CentralDeTaxi.java
Para poder se comunicar com a central de táxi, tanto os táxis quanto os passageiros devem ter
uma referência para a central. Essas ligações podem ser estabelecidas através dos construtores dasclasses Passageiro e Taxi.
90 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 95/121
91 P ADRÕES COMPORTAMENTAIS
1 p u b li c c l a ss P a s s ag e i r o {
2 private CentralDeTaxi central;
3 public P a s s ag e i ro ( C e n t r a l De T a x i c e n tr a l ) {
4 this . c e n t ra l = c e n tr a l ;
5 }6 }
Código Java 4.24: Passageiro.java
1 p u b li c c l a ss T ax i {
2 private CentralDeTaxi central;
3 public T a xi ( C e n t r a lD e T a xi c e n tr a l ) {
4 this . c e n t ra l = c e n tr a l ;
5 }
6 }
Código Java 4.25: Taxi.java
Organização
O diagrama UML abaixo ilustra a organização desse padrão.
Figura 4.5: UML do padrão Mediator
Os personagens desse padrão são:
MediatorInterface que padroniza as operações que serão chamadas pelos Colleagues.
ConcreateMediator (CentralDeTaxi)Implementação particular do Mediator, que coordena a interação entre os Colleagues.
ColleaguePossível interface para padronizar os ConcreateColleagues .
ConcreateColleague (Taxi, Passageiro)Classes que interagem entre si por meio do Mediator.
Exercícios de Fixação
10 Crie um projeto chamado Mediator.
11 Defina as classes Passageiro, Taxi e CentralDeTaxi.
www.k19.com.br 91
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 96/121
P ADRÕES COMPORTAMENTAIS 92
1 p u b li c c l a ss P a s s ag e i r o {
2 private CentralDeTaxi central;
3 public P a s s ag e i ro ( C e n t r a l De T a x i c e n tr a l ) {
4 this . c e n t ra l = c e n tr a l ;
5 }6 }
Código Java 4.26: Passageiro.java
1 p u b li c c l a ss T ax i {
2 private CentralDeTaxi central;
3 public T a xi ( C e n t r a lD e T a xi c e n tr a l ) {
4 this . c e n t ra l = c e n tr a l ;
5 }
6 }
Código Java 4.27: Taxi.java
1 p u b li c c l a ss C e n t ra l D e Ta x i {
2 private L i st < T a x i > t a x i sL i v r es = ne w ArrayList <Taxi >();
3 private List<Passageiro > passageirosEmEspera = ne w ArrayList <Passageiro >();
4
5 p u b li c v o id a d i c i on a T a xi D i s p on i v e l ( T a xi t a xi ) {
6 / / i m p l em e n t aç ã o
7 }
8
9 p u b li c v o id p e d e Ta x i ( P a s s ag e i r o p a s s ag e i ro ) {
1 / / i m p l em e n t aç ã o
11 }
12 }
Código Java 4.28: CentralDeTaxi.java
12 Adicione à classe Passageiro um método para simular a chegada de passageiros. Adicionetambém um atributo para identificar o passageiro.
1 p u b li c c l a ss Passageiro implements R u n na b l e {
2 private S t r in g n o me ;
3 private CentralDeTaxi central;
4
5 public P a s s ag e i ro ( S t r i n g n om e , C e n t ra l D e Ta x i c e n tr a l ) {
6 this . n om e = n om e ;
7 this . c e n t ra l = c e n tr a l ;
8 }
9
1 public S t r in g g e t No m e ( ) {
11 return nome;
12 }
1314 p u b li c v o id r un ( ) {
15 fo r ( in t i = ; i < 5; i ++) {
16 this .central.pedeTaxi( this );
17 }
18 }
19 }
Código Java 4.29: Passageiro.java
13 Adicione à classe Taxi um método para simular uma corrida de táxi. Adicione também umatributo para identificar o táxi.
1 p u b li c c l a ss T ax i {
2 private CentralDeTaxi central;3 p r i va t e i n t id ;
4 p r i va t e s t a ti c i n t c o nt a do r = ;
92 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 97/121
93 P ADRÕES COMPORTAMENTAIS
5
6 public T a xi ( C e n t r a lD e T a xi c e n tr a l ) {
7 this . c e n t ra l = c e n tr a l ;
8 this . i d = T a xi . c o n t a do r + + ;
9 }
111 p u b li c i n t g e t Id ( ) {
12 return id ;
13 }
14
15 p u b li c v o id a t e nd e ( ) {
16 tr y {
17 Thread . sleep (( long ) ( M a t h . r an d o m ( ) * 3 . ) ) ;
18 } catch ( I n t e r r u pt e d E xc e p t i on e ) {
19 e. printStackTrace () ;
2 }
21 this .central.adicionaTaxiDisponivel( this ) ;
22 }
23 }
Código Java 4.30: Taxi.java
14 Implemente o método adicionaTaxiDisponivel() da classe CentralDeTaxi. Esse métododeve receber um Taxi como parâmetro e adicioná-lo à fila de táxis livres.
1 p u b li c c l a ss C e n t ra l D e Ta x i {
2 private L i st < T a x i > t a x i sL i v r es = ne w ArrayList <Taxi >();
3 private List<Passageiro > passageirosEmEspera = ne w ArrayList <Passageiro >();
4
5 p u b li c s y n c hr o n i ze d v o id a d i c i on a T a xi D i s p on i v e l ( T a xi t a xi ) {
6 System . out . println ( " T ax i " + t ax i . ge t Id ( ) + " v o lt o u p r a f il a ");
7 taxisLivres .add ( taxi );
8 this .notifyAll();
9 }
1 }
Código Java 4.31: CentralDeTaxi.java
15 Implemente o método pedeTaxi() da classe CentralDeTaxi. Esse método deve receber umPassageiro como parâmetro e adicioná-lo à fila de passageiros.
1 p u b li c c l a ss C e n t ra l D e Ta x i {
2 private L i st < T a x i > t a x i sL i v r es = ne w ArrayList <Taxi >();
3 private List<Passageiro > passageirosEmEspera = ne w ArrayList <Passageiro >();
4
5 p u b li c s y n c hr o n i ze d v o id a d i c i on a T a xi D i s p on i v e l ( T a xi t a xi ) {
6 System . out . println ( " T ax i " + t ax i . ge t Id ( ) + " v o lt o u p r a f il a ") ;
7 taxisLivres .add ( taxi );
8 this .notifyAll();9 }
1
11 p u b li c v o id p e d e Ta x i ( P a s s ag e i r o p a s s ag e i ro ) {
12 Taxi taxi = this .esperaTaxi(passageiro);
13 System . out . println ( " T ax i " + t ax i . ge t Id ( ) + " l e va nd o " + p a s s ag e i r o . g e tN o m e ( )←
) ;
14 taxi . atende () ;
15 }
16
17 private T a xi e s p er a T a xi ( P a s s a g ei r o p a s s ag e i r o ) {
18 this .passageirosEmEspera.add(passageiro);
19 synchronized ( this ) {
2 while ( this .taxisLivres.isEmpty()
21 || ! this .passageirosEmEspera. get().equals(passageiro)) {
22 tr y {
23 this .wait();24 } catch ( I n t e r r up t e d E xc e p t i on e ) {
25 e. printStackTrace () ;
www.k19.com.br 93
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 98/121
P ADRÕES COMPORTAMENTAIS 94
26 }
27 }
28 this .passageirosEmEspera.remove();
29 r e t ur n t h is .taxisLivres.remove();
3 }
31 }32 }
Código Java 4.32: CentralDeTaxi.java
16 Crie uma classe para simular o sistema.
1 p u b li c c l a ss T e s t a Ce n t r al D e T a xi {
2 p u b li c s t a ti c v o id m a i n ( S tr i n g [] a r gs ) {
3 CentralDeTaxi central = ne w CentralDeTaxi();
4
5 Passageiro p1 = ne w Passageiro(" R a f a el C o s en t i n o ", c e n tr a l ) ;
6 Passageiro p2 = ne w Passageiro(" M a r c el o M a r ti n s ", c e n tr a l ) ;
7 Passageiro p3 = ne w Passageiro(" J o n as H i r at a " , c e n tr a l ) ;
8
9 Taxi t1 = ne w Taxi(central);
1 c en tr al . ad ic io na Tax iD is po ni ve l( t1 );
11
12 Taxi t2 = ne w Taxi(central);
13 c en tr al . ad ic io na Tax iD is po ni ve l( t2 );
14
15 ne w Thread(p1).start();
16 ne w Thread(p2).start();
17 ne w Thread(p3).start();
18 }
19 }
Código Java 4.33: TestaCentralDeTaxi.java
Observer
Objetivo: Definir um mecanismo eficiente para reagir às alterações realizadas em determinados
objetos.
Considere um supermercado em que os caixas possuem uma fila única. Cada caixa é identificadopor um número, que é exibido em uma placa à sua frente. Esse número fica visível à todos os clientesda fila.
Também visível aos clientes da fila, existe um painel que exibe o número de identificação dopróximo caixa disponível (se houver algum).
94 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 99/121
95 P ADRÕES COMPORTAMENTAIS
Figura 4.6: Fila dos caixas de um supermercado e o seu painel
O painel precisa saber sobre as mudanças no estado (livre ou ocupado) de cada caixa para atua-lizar o seu mostrador.
Uma possibilidade é fazer o painel consultar, periodicamente, o estado de cada caixa. Contudo,essa pode ser uma abordagem ineficiente, principalmente quando o estado dos caixas não é alteradofrequentemente.
Uma outra possibilidade é fazer com que cada caixa avisasse ao painel sobre uma mudança emseu estado.
Nessa abordagem, no momento em que um caixa fica disponível ou ocupado, ele poderia passaro seu número de identificação para o painel, para informá-lo sobre a sua mudança de estado. Opainel, por sua vez, atualizaria o número exibido quando necessário.
A ideia fundamental do padrão Observer é atribuir aos objetos que tem seus estados alterados a
tarefa de notificar os objetos interessados nessas mudanças. Em nosso exemplo, os caixas notificamo painel sobre alterações em seus estados.
www.k19.com.br 95
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 100/121
P ADRÕES COMPORTAMENTAIS 96
Exemplo prático
Estamos desenvolvendo um sistema para o mercado financeiro. Esse sistema deve manter todos
os interessados em uma determinada ação informados do valor da mesma. Toda alteração no valorde uma ação deve ser informada aos seus respectivos interessados.
Podemos ter vários tipos de interessados. Por exemplo, uma pessoa física, uma empresa, um ór-gão público, entre outros. Para manter uma padronização na modelagem, definiremos uma interfacepara os interessados.
1 publi interface A c a o Ob s e r ve r {
2 void notificaAlteracao(Acao acao);
3 }
Código Java 4.34: AcaoObserver.java
Agora, podemos implementar os interessados de maneira concreta.1 p u b li c c l a ss C o r re t o r a i m p l em e n t es A c a o Ob s e r ve r {
2
3 p u b li c v o id n o t i fi c a A l te r a c ao ( A c a o a c ao ) {
4 / / i m p l em e t a ca o
5 }
6 }
Código Java 4.35: Corretora.java
Por outro lado, a classe Acao deve aceitar interessados (observadores) e avisá-los quando o seuvalor for alterado.
1 p u b li c c l a ss A ca o {2
3 p r i va t e d o u bl e valor;
4 private Set<AcaoObserver > interessados = ne w HashSet <AcaoO bserver >();
5
6 p u b li c v o id r e g i st r a I n te r e s s ad o ( A c a o O b se r v e r i n t e re s s a do ) {
7 this .interessados.add(interessado);
8 }
9
1 p u b li c v o id c a n c el a I n te r e s s e ( A c a oO b s e rv e r i n t e re s s a do ) {
11 this .interessados.remove(interessado);
12 }
13
14 p u b li c d o u bl e g e t Va l o r ( ) {
15 r e t ur n t h is .valor;
16 }
1718 p u b li c v o id setValor( double v al o r ) {
19 this . v a lo r = v a lo r ;
2 fo r ( A c a o O bs e r v er i n t e re s s a do : this . i n t e r e ss a d o s ) {
21 interessado .notificaAlteracao (this );
22 }
23 }
24 }
Código Java 4.36: Acao.java
Organização
O diagrama UML abaixo ilustra a organização desse padrão.
96 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 101/121
97 P ADRÕES COMPORTAMENTAIS
Figura 4.7: UML do padrão Observer
Os personagens desse padrão são:
Observer (AcaoObserver)Interface dos objetos interessados no estado dos Subjects.
ConcreteObserver (Corretora)Implementação particular de um Observer.
SubjectInterface usada para padronizar os objetos que serão observados.
ConcreteSubject (Acao)Implementação de um Subject.
Exercícios de Fixação
17 Crie um projeto chamado Observer.
18 Defina a classe Acao.
1 p u b li c c l a ss A ca o {
2 private S t r in g c o d ig o ;
3 p r i va t e d o u bl e valor;4
5 public Acao(String codigo , double v a lo r ) {
6 this . c o d i go = c o d ig o ;
7 this . v a lo r = v a lo r ;
8 }
9
1 p u b li c d o u bl e g e t Va l o r ( ) {
11 return valor;
12 }
13
14 p u b li c v o id setValor( double v al o r ) {
15 this . v a lo r = v a lo r ;
16 }
17
18 public S t r in g g e t Co d i g o ( ) {
19 return codigo;2 }
21 }
www.k19.com.br 97
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 102/121
P ADRÕES COMPORTAMENTAIS 98
Código Java 4.37: Acao.java
19 Para notificar os interessados sobre as alterações nos valores da ação, devemos registrar os inte-ressados e notificá-los. Para padronizara notificaçãodos interessados, criemos a interface AcaoObserver.
1 public interface A c a o Ob s e r ve r {
2 void notificaAlteracao(Acao acao);
3 }
Código Java 4.38: AcaoObserver.java
20 Altere a classe Acao para registrar os interessados e notificá-los sobre a alteração no valor daação.
1 p u b li c c l a ss A ca o {
2 private S t r in g c o d ig o ;
3 p r i va t e d o u bl e valor;
4
5 private Set<AcaoObserver > interessados = ne w HashSet <AcaoO bserver >();
6
7 public Acao(String codigo , double v a lo r ) {
8 this . c o d i go = c o d ig o ;
9 this . v a lo r = v a lo r ;
1 }
11
12 p u b li c v o id r e g i st r a I n te r e s s ad o ( A c a o O b se r v e r i n t e re s s a do ) {
13 this .interessados.add(interessado);
14 }
15
16 p u b li c v o id c a n c el a I n te r e s s e ( A c a oO b s e rv e r i n t e re s s a do ) {
17 this .interessados.remove(interessado);
18 }19
2 p u b li c d o u bl e g e t Va l o r ( ) {
21 return valor;
22 }
23
24 p u b li c v o id setValor( double v al o r ) {
25 this . v a lo r = v a lo r ;
26 fo r ( A c a o O bs e r v er i n t e re s s a do : this . i n t e r e ss a d o s ) {
27 interessado .notificaAlteracao (this );
28 }
29 }
3
31 public S t r in g g e t Co d i g o ( ) {
32 return codigo;
33 }
34 }
Código Java 4.39: Acao.java
21 Defina a classe Corretora e implemente a interface AcaoObserver para que as corretoras sejamnotificadas sobre as alterações nos valores das ações.
1 p u b li c c l a ss Corretora implements A c a o Ob s e r ve r {
2 private S t r in g n o me ;
3
4 public C o r r et o r a ( S t ri n g n o me ) {
5 this . n om e = n om e ;
6 }
7
8 p u b li c v o id n o t i fi c a A l te r a c ao ( A c a o a c ao ) {9 System . out . println ( " C o r r et o r a " + this . n om e + " s e n do n o t i fi c a da : " ) ;
1 System . out . println ( " A a ç ão " + a c ao . g e t C o d ig o ( )
98 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 103/121
99 P ADRÕES COMPORTAMENTAIS
11 + " t ev e o s eu v al or a lt er ad o p ar a " + a c ao . g e t V a lo r ( ) ) ;
12 }
13 }
Código Java 4.40: Corretora.java
22 Faça uma classe para testar as classes Corretora e Acao.
1 p u b li c c l a ss T e s t aO b s e rv e r {
2 p u b li c s t a ti c v o id m a i n ( S tr i n g [] a r gs ) {
3 Acao acao = ne w Acao("VALE3" , 4 5 . 27 ) ;
4
5 Corretora corretora1 = ne w Corretora("Corretora1" ) ;
6 Corretora corretora2 = ne w Corretora("Corretora2" ) ;
7
8 acao . re gi st raI nt er es sa do ( co rr et or a1 );
9 acao . re gi st raI nt er es sa do ( co rr et or a2 );
1
11 acao . setValor (5) ;
12 }13 }
Código Java 4.41: TestaObserver.java
State
Objetivo: Alterar o comportamento de um determinado objeto de acordo com o estado no qual ele
se encontra.
Exemplo prático
Estamos trabalhando em uma empresa que vende taxímetros para o mundo todo. Temos queimplementar a lógica para calcular o valor das corridas de acordo com a bandeira selecionada noaparelho. O taxímetro pode ser configurado com diversas bandeiras.
Figura 4.8: Taxímetro e suas bandeiras
Vamos implementar uma interface para padronizar os métodos das bandeiras do taxímetro.
www.k19.com.br 99
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 104/121
P ADRÕES COMPORTAMENTAIS 100
1 public interface B a n de i r a {
2 double calculaValorDaCorrida( double tempo, double distancia);
3 }
Código Java 4.42: Bandeira.java
Agora, podemos implementar o taxímetro propriamente.
1 p u b li c c l a ss T a x im e t r o {
2 private B a n d ei r a b a n de i r a ;
3
4 public T a x i me t r o ( B a n de i r a b a n de i r a ) {
5 this . b a n d ei r a = b a n de i r a ;
6 }
7
8 p u b li c v o id s e t Ba n d e ir a ( B a n d e ir a b a n de i r a ) {
9 this . b a n d ei r a = b a n de i r a ;
1 }
1112 p u b li c d o u bl e calculaValorDaCorrida( double tempo, double d i s ta n c i a ) {
13 r e t ur n t h is .bandeira.calculaValorDaCorrida (tempo, distancia);
14 }
15 }
Código Java 4.43: Taximetro.java
Depois, é necessário definir as bandeiras do taxímetrode acordo comas necessidades locais, poisas regras de cálculo das corridas são diferentes para cada região.
1 p u b li c c l a ss Bandeira1 implements Bandeira{
2 p u b li c d o u bl e calculaValorDaCorrida( double tempo, double d i s ta n c i a ) {
3 return 5 . + t em po * 1 .5 + d is ta nc ia * 1 .7 ;4 }
5 }
Código Java 4.44: Bandeira1.java
1 p u b li c c l a ss Bandeira2 implements B a n de i r a {
2 p u b li c d o u bl e calculaValorDaCorrida( double tempo, double d i s ta n c i a ) {
3 return 1 . + t em po * 3 . + d is ta nc ia * 4 . ;
4 }
5 }
Código Java 4.45: Bandeira2.java
Por fim, o taxímetro deve ser utilizado da seguinte forma:
1 Ba nd ei ra b1 = ne w Bandeira1();
2 T ax im et ro t a xi me tr o = ne w Taximetro(b1);
3
4 double v a l or 1 = t a x i me t r o . c a l c ul a V a l or D a C or r i d a ( 1 , 2 ) ;
5 S ys t em . o ut . p r in t ln ( " V al o r d a c o rr i da e m b a nd e ir a 1 : " + v a l or 1 ) ;
6
7 Ba nd ei ra b2 = ne w Bandeira2();
8 t a xi m et r o . se t Ba n de i ra ( b 2 );
9
1 double v a l or 2 = t a x i me t r o . c a l c ul a V a l or D a C or r i d a ( 5 , 3 ) ;
11 S ys t em . o ut . p r in t ln ( " V al o r d a c o rr i da e m b a nd e ir a 2 : " + v a l or 2 ) ;
Código Java 4.46: Utilizando o taxímetro
100 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 105/121
101 P ADRÕES COMPORTAMENTAIS
Organização
O diagrama UML abaixo ilustra a organização desse padrão.
Figura 4.9: UML do padrão State
Os personagens desse padrão são:
State (Bandeira)Interface para padronizar os estados do Context.
ConcreteState (Bandeira1, Bandeira2)Implementação particular de um State.
Context (Taximetro)Mantém uma referência para um State que define o estado atual.
Exercícios de Fixação
23 Crie um projeto chamado State.
24 Defina uma interface para padronizar os métodos das bandeiras.
1 public interface B a n de i r a {
2 double calculaValorDaCorrida( double tempo, double distancia);
3 }
Código Java 4.47: Bandeira.java
25 Defina a classe Taximetro.
1 p u b li c c l a ss T a x im e t r o {
2 private B a n d ei r a b a n de i r a ;
3
4 public T a x i me t r o ( B a n de i r a b a n de i r a ) {
5 this . b a n d ei r a = b a n de i r a ;
6 }
7
8 p u b li c v o id s e t Ba n d e ir a ( B a n d e ir a b a n de i r a ) {
9 this . b a n d ei r a = b a n de i r a ;
1 }11
12 p u b li c v o id calculaValorDaCorrida( double tempo, double d i s t an c i a ) {
www.k19.com.br 101
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 106/121
P ADRÕES COMPORTAMENTAIS 102
13 this .bandeira.calculaValorDaCorrida (tempo, distancia);
14 }
15 }
Código Java 4.48: Taximetro.java
26 Implemente algumas classes que modelam a bandeira de um taxímetro.
1 p u b li c c l a ss Bandeira1 implements Bandeira{
2 p u b li c d o u bl e calculaValorDaCorrida( double tempo, double d i s ta n c i a ) {
3 return 5 . + t em po * 1 .5 + d is ta nc ia * 1 .7 ;
4 }
5 }
Código Java 4.49: Bandeira1.java
1 p u b li c c l a ss Bandeira2 implements B a n de i r a {
2 p u b li c d o u bl e calculaValorDaCorrida( double tempo, double d i s ta n c i a ) {
3 return 1 . + t em po * 3 . + d is ta nc ia * 4 . ;4 }
5 }
Código Java 4.50: Bandeira2.java
27 Teste a classe Taximetro.
1 p u b li c c l a ss T e s t aT a x i me t r o {
2 p u b li c s t a ti c v o id m a i n ( S tr i n g [] a r gs ) {
3 Bandeira b1 = ne w Bandeira1();
4 Bandeira b2 = ne w Bandeira2();
5
6 Taximetro taximetro = ne w Taximetro(b1);
78 double v a l or 1 = t a x i me t r o . c a l c u la V a l or D a C o rr i d a ( 1 , 2 ) ;
9 System . out . println ( " V al o r d a c o rr i da e m b a nd e ir a 1 : " + v a l or 1 ) ;
1
11 taximetro .setBandeira (b2 );
12
13 double v a l or 2 = t a x i me t r o . c a l c u la V a l or D a C o rr i d a ( 5 , 3 ) ;
14 System . out . println ( " V al o r d a c o rr i da e m b a nd e ir a 2 : " + v a l or 2 ) ;
15 }
16 }
Código Java 4.51: TestaTaximetro.java
Strategy
Objetivo: Permitir de maneira simples a variação dos algoritmos utilizados na resolução de um
determinado problema.
Quando desejamos percorrer um trajeto entre dois pontos numa cidade, precisamos decidir qualcaminho devemos seguir. Podem haver diversos caminhos entre dois pontos, o que pode tornar aescolha de um bom caminho um pouco difícil.
Existem algumas aplicações que podem ajudar nessa tarefa, como é o caso do Google Maps, porexemplo. Normalmente, essas aplicações permitem que o usuário escolha a forma (à pé, de bicicleta,
de carro, ou usando o transporte público) que deseja percorrer o caminho. Essa escolha afeta ospassos para se chegar ao destino final.
102 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 107/121
103 P ADRÕES COMPORTAMENTAIS
Figura 4.10: Diferentes modos de se chegar a um determinado destino
O padrão Strategy propõe uma solução que pode ser adotada nesse cenário. A ideia fundamentaldesse padrão é possibilitar facilmente a variação do algoritmo a ser utilizado na resolução de umproblema. Em nosso exemplo, diferentes algoritmos são usados para se encontrar uma rota entre
dois pontos, dependendo do modo como o usuário deseja percorrer o caminho.
Exemplo prático
Uma tarefa muito comum no desenvolvimento de uma aplicação é ordenar uma lista de elemen-tos. Em Ciência da Computação, foram desenvolvidos diversos algoritmos de ordenação. Podemosescolher o algoritmo mais apropriado de acordo com a situação.
De qualquer forma, todos os algoritmos de ordenação devem produzir o mesmo resultado, po-dendo variar no consumo de memória e no tempo gasto para realizar a ordenação.
Podemos definir uma interface para padronizar as diversas implementações dos algoritmos deordenação.
www.k19.com.br 103
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 108/121
P ADRÕES COMPORTAMENTAIS 104
1 public interface S o r te r {
2 <T extends Comparable <? super T > > L i st < T > s o rt ( L i st < T > l i st ) ;
3 }
Código Java 4.52: Sorter.java
Agora, podemos criar uma classe para cada algoritmo que vamos implementar.
1 p u b li c c l a ss InsertionSorter implements S o r te r {
2 public <T extends Comparable <? super T > > L is t < T > s or t ( Li st < T > l is t ) {
3 / / i m p l em e n t aç ã o
4 }
5 }
Código Java 4.53: InsertionSorter.java
1 p u b li c c l a ss BubbleSorter implements S o r te r {
2 public <T extends Comparable <? super T > > L is t < T > s or t ( Li st < T > l is t ) {
3 / / i m p l em e n t aç ã o
4 }
5 }
Código Java 4.54: BubbleSorter.java
Agora podemos escolher qual algoritmo utilizar quando desejamos ordenar uma lista de elemen-tos.
1 L is t < St ri ng > l is ta = . ..
2
3 I n se r ti o nS o rt e r i n se r ti o nS o rt e r = ne w InsertionSorter();
4 B u bb l eS o rt e r b ub b le S or t er = ne w BubbleSorter();
56 L i st < S t r i ng > l i s ta 1 = i n s e rt i o n S or t e r . s o rt ( l i s t a ) ;
7
8 L i st < S t r i ng > l i s ta 2 = b u b b le S o r te r . s o r t ( l is t a ) ;
Código Java 4.55: Ordenando
Organização
O diagrama UML abaixo ilustra a organização desse padrão.
Figura 4.11: UML do padrão Strategy
Os personagens desse padrão são:
104 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 109/121
105 P ADRÕES COMPORTAMENTAIS
Strategy (Sorter)Interface para padronizar as diferentes estratégias de um algoritmo.
ConcreteStrategy (InsertionSorter, BubbleSorter)
Implementação particular de um Strategy.
ContextMantém uma referência para um objeto Strategy e pode permitir que esse acesse os seusdados.
Exercícios de Fixação
28 Crie um projeto chamado Strategy .
29 Defina a interface Sorter.
1 public interface S o r te r {
2 <T extends Comparable <? super T > > L i st < T > s o rt ( L i st < T > l i st ) ;
3 }
Código Java 4.56: Sorter.java
30 Defina as implementações InsertionSorter e SelectionSorter.
1 p u b li c c l a ss InsertionSorter implements S o r te r {
2 public <T extends Comparable <? super T > > L is t < T > s or t ( Li st < T > l is t ) {
3 list = ne w ArrayList <T>(list);
4 fo r ( in t i = 1 ; i < l is t .s iz e () ; i + + ) {
5 T a = list . get ( i);
6 in t j;
7 fo r ( j = i - 1 ; j >= & & l is t .g et ( j) . co mp ar eT o (a ) > ; j - - ) {
8 list . remove (j + 1) ;
9 list . add (j + 1, list . get (j));
1 list . remove (j);
11 list . add (j , a);
12 }
13 }
14 return list;
15 }
16 }
Código Java 4.57: InsertionSorter.java
1 p u b li c c l a ss SelectionSorter implements S o r te r {
2 public <T extends Comparable <? super T > > L is t < T > s or t ( Li st < T > l is t ) {
3 in t index_min;
4 T aux ;
5 list = ne w ArrayList <T>(list);
6 fo r ( in t i = ; i < l is t .s iz e () ; i + + ) {
7 index_min = i;
8 fo r ( in t j = i + 1; j < l is t. si ze () ; j + +) {
9 if ( l i s t . ge t ( j ) . c o mp a r e To ( l i s t . g et ( i n d e x _m i n ) ) < ) {
1 index_min = j;
11 }
12 }
13 if ( i n de x _m i n ! = i ) {
14 aux = list . get ( index_min );
15 list . remove ( index_min );16 list . add ( index_min , list . get ( i));
17 list . remove (i);
www.k19.com.br 105
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 110/121
P ADRÕES COMPORTAMENTAIS 106
18 list . add (i , aux ) ;
19 }
2 }
21 return list;
22 }
23 }
Código Java 4.58: SelectionSorter.java
31 Faça uma classe para testar as diferentes estratégias de ordenação.
1 p u b li c c l a ss T e s t eS o r t er {
2 p u b li c s t a ti c v o id m a i n ( S tr i n g [] a r gs ) {
3 Sorter sorter = ne w InsertionSorter();
4 List < Integer > list = ne w ArrayList <Integer >();
5 list . add (1) ;
6 list . add (3) ;
7 list . add (2) ;
8 list . add (14) ;
9
1 List < Integer > l ist2 = s or ter . sort (list );
11 fo r ( I n te g er i n te g er : l is t2 ) {
12 System . out . println ( integer );
13 }
14
15 Sorter sorter2 = ne w SelectionSorter();
16 List < Integer > l ist3 = so rte r2 . sort (list );
17 fo r ( I n te g er i n te g er : l is t3 ) {
18 System . out . println ( integer );
19 }2 }
21 }
Código Java 4.59: TesteSorter.java
Template Method
Objetivo: Definir a ordem na qual determinados passos devem ser realizados na resolução de um
problema e permitir que esses passos possam ser realizados de formas diferentes de acordo com a situ-
ação.
Em 1913, Henry Ford introduziu o conceito de linha de montagem na produção de carros. Esseprocesso permiti até hoje que carros sejam produzidos em grande escala. Em geral, toda linha demontagem de carros possui três etapas fundamentais: corte das chapas de aço, pintura do esqueletodo carro e montagem dos componentes elétricos e mecânicos.
Em geral, essas três etapas são realizadas na mesma ordem independentemente do tipo de carro
que está sendo produzido. Contudo, obviamente, para cada tipo de carro, essas etapas são realizadasde maneiras diferentes.
106 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 111/121
107 P ADRÕES COMPORTAMENTAIS
Figura 4.12: Duas linhas de montagens de carros diferentes
O padrão de projeto Template Method possui características semelhantes às linhas de monta-
gens de carros. A ideia fundamental desse padrão é definir a ordem de execução dos passos queresolvem um determinado problema e permitir que cada passo possa ser implementado de manei-ras diferentes.
Exemplo prático
Estamos desenvolvendo um sistema bancário e precisamos modelar os diversos tipos de contasdo banco. Decidimos aplicar herança utilizando uma classe chamada Conta.
1 p u b li c a b s t ra c t c l a ss C o nt a {
2 p r i va t e d o u bl e saldo;
34 p u b li c v o id deposita( double v al o r ) {
5 this . s a ld o + = v a lo r ;
6 }
7
8 p u b li c v o id saca( double v al o r ) {
9 this . s a ld o - = v a lo r ;
1 }
11 }
Código Java 4.60: Conta.java
Toda operação bancária realizada gera a cobrança de uma taxa que é diferente para cada tipo daconta. Podemos tentar implementar um método para calcular essa taxa na classe Conta e chamá-loa partir dos outros métodos.
1 p u b li c a b s t ra c t c l a ss C o nt a {
2 p r i va t e d o u bl e saldo;
3
4 p u b li c v o id deposita( double v al o r ) {
5 this . s a ld o + = v a lo r ;
6 this . s a l do - = this .calculaTaxa();
7 }
8
9 p u b li c v o id saca( double v al o r ) {
1 this . s a ld o - = v a lo r ;
11 this . s a l do - = this .calculaTaxa();
12 }
13
14 p u b li c d o u bl e calculaTaxa(){15 / / i m p l em e n t aç ã o
16 }
www.k19.com.br 107
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 112/121
P ADRÕES COMPORTAMENTAIS 108
17 }
Código Java 4.61: Conta.java
Contudo, nada pode ser definido no corpo do método calculaTaxa() na classe Conta porque ocálculo é diferente para cada tipo de conta bancária. A solução é tornar o método abstrato para queele seja implementado nas classes das contas específicas. Dessa forma, os métodos que chamam ocalculaTaxa() dependem de um método que será implementado posteriormente.
1 p u b li c a b s t ra c t c l a ss C o nt a {
2 p r i va t e d o u bl e saldo;
3
4 p u b li c v o id deposita( double v al o r ) {
5 this . s a ld o + = v a lo r ;
6 this . s a l do - = this .calculaTaxa();
7 }
8
9 p u b li c v o id saca( double v al o r ) {
1 this . s a ld o - = v a lo r ;11 this . s a l do - = this .calculaTaxa();
12 }
13
14 p u b li c a b s tr a c t d o u bl e calculaTaxa();
15 }
Código Java 4.62: Conta.java
1 p u b li c c l a ss ContaPoupanca extends C o nt a {
2 p u b li c d o u bl e c a l c ul a T a xa ( ) {
3 return .5;
4 }
5 }
Código Java 4.63: ContaPoupanca.java
1 p u b li c c l a ss ContaCorrente extends C o nt a {
2 p u b li c d o u bl e c a l c ul a T a xa ( ) {
3 return .1;
4 }
5 }
Código Java 4.64: ContaCorrente.java
Organização
O diagrama UML abaixo ilustra a organização desse padrão.
Figura 4.13: UML do padrão Template Method
108 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 113/121
109 P ADRÕES COMPORTAMENTAIS
Os personagens desse padrão são:
AbstractClass (Conta)
Classe abstrata que define os templates methods baseados em métodos abstratos que serãoimplementados nas ConcreteClasses.
ConcreteClass (ContaCorrente, ContaPoupanca)Classes concretas que implementam os métodos abstratos definidos pela AbstractClass eque são utilizados pelos templates methods.
Exercícios de Fixação
32 Crie um projeto chamado TemplateMethod.
33 Defina a classe Conta e o método abstrato calculaTaxa. A cada operação uma taxa é cobrada.
1 p u b li c a b s t ra c t c l a ss C o nt a {
2 p r i va t e d o u bl e saldo;
3
4 p u b li c v o id deposita( double v al o r ) {
5 this . s a ld o + = v a lo r ;
6 this . s a l do - = this .calculaTaxa();
7 }
8
9 p u b li c v o id saca( double v al o r ) {
1 this . s a ld o - = v a lo r ;
11 this . s a l do - = this .calculaTaxa();
12 }13
14 p u b li c d o u bl e g e t Sa l d o ( ) {
15 return saldo;
16 }
17
18 p u b li c a b s tr a c t d o u bl e calculaTaxa();
19 }
Código Java 4.65: Conta.java
34 Defina as classes ContaCorrente e ContaPoupanca derivadas de Conta. As classes deverão defi-nir a taxa que será cobrada.
1 p u b li c c l a ss ContaCorrente extends C o nt a {2 p u b li c d o u bl e c a l c ul a T a xa ( ) {
3 return 3;
4 }
5 }
Código Java 4.66: ContaCorrente.java
1 p u b li c c l a ss ContaPoupanca extends C o nt a {
2 p u b li c d o u bl e c a l c ul a T a xa ( ) {
3 return 1;
4 }
5 }
Código Java 4.67: ContaPoupanca.java
35 Teste as classes ContaCorrente e ContaPoupanca.
www.k19.com.br 109
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 114/121
P ADRÕES COMPORTAMENTAIS 110
1 p u b li c c l a ss T e s t aC o n t as {
2 p u b li c s t a ti c v o id m a i n ( S tr i n g [] a r gs ) {
3 Conta contaCorrente = ne w ContaCorrente();
4 Conta contaPoupanca = ne w ContaPoupanca();
56 contaCorrente .deposita (1) ;
7 contaCorrente .saca (1) ;
8
9 contaPoupanca .deposita (1) ;
1 contaPoupanca .saca (1) ;
11
12 System . out . println ( " S al d o d a C on t a C o rr e nt e : "
13 + contaCorrente . getSaldo () );
14 System . out . println ( " S al d o d a C on t a P o up a nç a : "
15 + contaPoupanca . getSaldo () );
16 }
17 }
Código Java 4.68: TestaContas.java
Visitor
Objetivo: Permitir atualizações específicas em uma coleção de objetos de acordo com o tipo parti-
cular de cada objeto atualizado.
Exemplo prático
Estamos desenvolvendo um sistema bancário no qual os funcionários devem ser classificados deacordo com o cargo que eles possuem. Para modelar as diferenças e semelhanças relativas a cadacargo decidimos aplicar o conceito de herança na nossa modelagem.
1 p u b li c a b s t ra c t c l a ss F u n c io n a ri o {
2 private S t r in g n o me ;
3 p r i va t e d o u bl e salario;
4
5 / / G E T TE R S A N D S E T T E R S
6 }
Código Java 4.69: Funcionario.java
1 p u b li c c l a ss G e r en t e {
2 p r i va t e i n t senha;
3
4 / / G E T TE R S A N D S E T T E R S
5 }
Código Java 4.70: Gerente.java
1 p u b li c c l a ss T e l e fo n i s ta {
2 p r i va t e i n t ramal;
3
4 / / G E T TE R S A N D S E T T E R S
5 }
Código Java 4.71: Telefonista.java
Todo funcionário do banco está associado a um departamento. Podemos aplicar agregação paraimplementar essa condição.
110 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 115/121
111 P ADRÕES COMPORTAMENTAIS
1 p u b li c c l a ss D e p a rt a m e nt o {
2 private List<Funcionario > funcionarios;
3
4 }
Código Java 4.72: Departamento.java
De tempos em tempos, os salários dos funcionários são reajustados. O reajuste do salário deum funcionário depende basicamente do cargo que ele possui. Além dessa, outras alterações nasinformações dos objetos que representam os funcionários podem ocorrer de tempos em tempos.
Podemos implementar o reajuste ou qualquer outra tarefa de atualização dos dados dos funcio-nários através de classes especializadas. Inclusive, podemos definir uma interface para padronizar ainteração com essas classes.
1 public interface AtualizadorDeFuncionario {
2 void a t u al i z a ( G e re n t e g ) ;
3 void a t u al i z a ( T e l ef o n i st a t ) ;
4 }
Código Java 4.73: AtualizadorDeFuncionario.java
1 p u b li c c l a ss AtualizadorSalarial implements AtualizadorDeFuncionario {
2 p u b li c v o id a t u a li z a ( G e r en t e g ) {
3 g. setSalario (g. getSalario () * 1.43) ;
4 }
5 p u b li c v o id a t u a li z a ( T e l e fo n i s ta t ) {
6 t. setSalario (t. getSalario () * 1.27) ;
7 }
8 }
Código Java 4.74: AtualizadorSalarial.java
Agora, suponha que no sistema há uma lista com todos os departamentos do banco. Queremosaplicar um atualizador em todos os funcionários de todos os departamentos dessa lista.
O esqueleto do código seria mais ou menos assim:
1 L is t < D ep a rt a me nt o > l is t a = . ..
2 A t ua l iz a do r De F un c io n ar i o a t u a li z ad o r = . ..
3
4 fo r ( D e pa r ta m en t o d : l i st a ) {
5 / / a t u a li z a n do . . .
6 }
Código Java 4.75: Aplicando um atualizador
Contudo temos dois problemas: primeiro, é possível que o acesso aos funcionários de um depar-tamento esteja restrito, consequentemente, dentro do laço acima não poderíamos executar o atuali-zador. Segundo, mesmo que o acesso esteja disponível, teríamos que testar o tipo dos funcionáriosde cada departamento para selecionar o método correto de atualização.
1 L is t < D ep a rt a me nt o > l is t a = . ..
2 A t ua l iz a do r De F un c io n ar i o a t u a li z ad o r = . ..
3
4 fo r ( D e pa r ta m en t o d : l i st a ) {
5 fo r ( F u n c i on a r i o f : d . g e t F u nc i o n ar i o s ( ) ) {
6 if (f instanceof G e r en t e ) {
7 Gerente g = ( Gerente )f;8 atualizador . atualiza (g);
9 } else {
www.k19.com.br 111
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 116/121
P ADRÕES COMPORTAMENTAIS 112
1 Telefonista t = ( Telefonista )f;
11 atualizador . atualiza (t);
12 }
13 }
14 }
Código Java 4.76: Aplicando um atualizador
Para solucionar os dois problemas acima, podemos passar os atualizadores para dentro dos de-partamentos e dos funcionários para que eles próprios chamem o método correto de atualização. Osatualizadores podem ser passados para dentro dos departamentos e dos funcionários através de ummétodo padronizado por uma interface.
1 public interface A t u a li z a v el {
2 void aceita(AtualizadorDeFuncionario atualizador);
3 }
Código Java 4.77: Atualizavel.java
1 p u b li c a b s t ra c t c l a ss Funcionario implements A t u a li z a v el {
2 private S t r in g n o me ;
3 p r i va t e d o u bl e salario;
4
5 / / G E T TE R S A N D S E T T E R S
6 }
Código Java 4.78: Funcionario.java
1 p u b li c c l a ss G e r en t e {
2 p r i va t e i n t senha;
3
4 p u b li c v o id a c e it a ( A t u a l i za d o r D eF u n c i on a r i o a t u a li z a do r ) {
5 atualizador . atualiza ( this );
6 }7
8 / / G E T TE R S A N D S E T T E R S
9 }
Código Java 4.79: Gerente.java
1 p u b li c c l a ss T e l e fo n i s ta {
2 p r i va t e i n t ramal;
3
4 p u b li c v o id a c e it a ( A t u a l i za d o r D eF u n c i on a r i o a t u a li z a do r ) {
5 atualizador . atualiza ( this );
6 }
7
8 / / G E T TE R S A N D S E T T E R S
9 }
Código Java 4.80: Telefonista.java
O departamento também é atualizável.
1 p u b li c c l a ss Departamento implements A t u a li z a v el {
2 private List<Funcionario > funcionarios;
3
4 p u b li c v o id a c e it a ( A t u a l i za d o r D eF u n c i on a r i o a t u a li z a do r ) {
5 fo r ( F u nc i on a ri o f : this . f u n c i on a r i os ) {
6 f. aceita ( atualizador );
7 }
8 }
9 }
Código Java 4.81: Departamento.java
112 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 117/121
113 P ADRÕES COMPORTAMENTAIS
Agora, aplicar um atualizador em todos os funcionários de todos os departamentos da lista dedepartamentos do sistema se torna simples:
1 L is t < D ep a rt a me nt o > l is t a = . ..
2 A t ua l iz a do r De F un c io n ar i o a t u a li z ad o r = . ..
34 fo r ( D e pa r ta m en t o d : l i st a ) {
5 d .ac eit a( atu ali za do r) ;
6 }
Código Java 4.82: Aplicando um atualizador
Organização
O diagrama UML abaixo ilustra a organização desse padrão.
Figura 4.14: UML do padrão Visitor
Os personagens desse padrão são:
Visitor (AtualizadorDeFuncionario)Define a interface dos objetos responsáveis pelas atualizações dos Elements.
ConcreteVisitor (AtualizadorSalarial)Implementa a lógica de uma determinada atualização dos Elements.
Element (Atualizavel)Define a interface dos objetos que podem ser atualizados por um Visitor.
ConcreteElement (Funcionario, Departamento)Define um tipo específico de Element.
www.k19.com.br 113
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 118/121
P ADRÕES COMPORTAMENTAIS 114
ObjectStructure Agregador dos Elements.
Client
Aplica um determinado Visitor nos Elements do ObjectStructure.
Exercícios de Fixação
36 Crie um projeto chamado Visitor.
37 Defina as classes Funcionario, Gerente, Telefonista e Departamento.
1 p u b li c a b s t ra c t c l a ss F u n c io n a ri o {
2 private S t r in g n o me ;
3 p r i va t e d o u bl e salario;
4
5 public F u n c io n a r io ( S t r i n g n o me , double s a l ar i o ) {
6 this . n om e = n om e ;
7 this . s a l a ri o = s a l ar i o ;
8 }
9
1 public S t r in g g e t No m e ( ) {
11 return nome;
12 }
13
14 p u b li c d o u bl e g e t S al a r i o ( ) {
15 return salario;
16 }
17
18 p u b li c v o id setSalario( double s a l ar i o ) {19 this . s a l a ri o = s a l ar i o ;
2 }
21 }
Código Java 4.83: Funcionario.java
1 p u b li c c l a ss Gerente extends F u n ci o n a ri o {
2 private S t r in g s e nh a ;
3
4 public G e r en t e ( S t r in g n o me , double s a la r io , S t r in g s e n ha ) {
5 super ( n o me , s a l ar i o ) ;
6 this . s e nh a = s e nh a ;
7 }
8
9 public S t r in g g e t Se n h a ( ) {1 return senha;
11 }
12 }
Código Java 4.84: Gerente.java
1 p u b li c c l a ss Telefonista extends F u n c io n a r io {
2 p r i va t e i n t ramal;
3
4 public T e l e fo n i s ta ( S t r i n g n o me , double salario , in t r a ma l ) {
5 super ( n o me , s a l ar i o ) ;
6 this . r a ma l = r a ma l ;
7 }
8
9 p u b li c i n t g e t Ra m a l ( ) {1 return ramal;
11 }
114 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 119/121
115 P ADRÕES COMPORTAMENTAIS
12 }
Código Java 4.85: Telefonista.java
1 p u b li c c l a ss D e p a rt a m e nt o {2 private S t r in g n o me ;
3 private List<Funcionario > funcionarios = ne w ArrayList <Funcionario >();
4
5 public D e p a rt a m e nt o ( S t r i ng n o me ) {
6 this . n om e = n om e ;
7 }
8
9 public S t r in g g e t No m e ( ) {
1 return nome;
11 }
12
13 public List<Funcionario > getFuncionarios() {
14 return funcionarios;
15 }
16 }
Código Java 4.86: Departamento.java
38 Defina a interface AtualizadorDeFuncionario e a implementação AtualizadorSalarial.
1 public interface AtualizadorDeFuncionario {
2 void a t u al i z a ( G e re n t e g ) ;
3 void a t u al i z a ( T e l ef o n i st a t ) ;
4 }
Código Java 4.87: AtualizadorDeFuncionario.java
1 p u b li c c l a ss AtualizadorSalarial implements AtualizadorDeFuncionario {
2 p u b li c v o id a t u a li z a ( G e r en t e g ) {
3 g. setSalario (g. getSalario () * 1.43) ;
4 }
5 p u b li c v o id a t u a li z a ( T e l e fo n i s ta t ) {
6 t. setSalario (t. getSalario () * 1.27) ;
7 }
8 }
Código Java 4.88: AtualizadorSalarial.java
39 Crie a interface Atualizavel.
1 public interface A t u a li z a v el {
2 void aceita(AtualizadorDeFuncionario atualizador);
3 }
Código Java 4.89: Atualizavel.java
40 Altere a classe Funcionario e assine a interface Atualizavel.
1 a b s tr a c t p u b li c c l a ss Funcionario implements A t u a li z a v el {
2 ...
3 }
Código Java 4.90: Funcionario.java
41 Implemente a interface Atualizavel.
1 p u b li c c l a ss Gerente extends F u n ci o n a ri o {2 private S t r in g s e nh a ;
3
www.k19.com.br 115
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 120/121
P ADRÕES COMPORTAMENTAIS 116
4 public G e r en t e ( S t r in g n o me , double s a la r io , S t r in g s e n ha ) {
5 super ( n o me , s a l ar i o ) ;
6 this . s e nh a = s e nh a ;
7 }
8
9 public S t r in g g e t Se n h a ( ) {1 return senha;
11 }
12
13 p u b li c v o id a c e it a ( A t u a l i za d o r D eF u n c i on a r i o a t u a li z a do r ) {
14 atualizador .atualiza (this );
15 }
16 }
Código Java 4.91: Gerente.java
1 p u b li c c l a ss Telefonista extends F u n c io n a r io {
2 p r i va t e i n t ramal;
3
4 public T e l e fo n i s ta ( S t r i n g n o me , double salario , in t r a ma l ) {
5 super ( n o me , s a l ar i o ) ;6 this . r a ma l = r a ma l ;
7 }
8
9 p u b li c i n t g e t Ra m a l ( ) {
1 return ramal;
11 }
12
13 p u b li c v o id a c e it a ( A t u a l i za d o r D eF u n c i on a r i o a t u a li z a do r ) {
14 atualizador .atualiza (this );
15 }
16 }
Código Java 4.92: Telefonista.java
1 p u b li c c l a ss D e p a rt a m e nt o {2 private S t r in g n o me ;
3 private List<Funcionario > funcionarios = ne w ArrayList <Funcionario >();
4
5 public D e p a rt a m e nt o ( S t r i ng n o me ) {
6 this . n om e = n om e ;
7 }
8
9 public S t r in g g e t No m e ( ) {
1 return nome;
11 }
12
13 public List<Funcionario > getFuncionarios() {
14 return funcionarios;
15 }
16
17 p u b li c v o id a c e it a ( A t u a l i za d o r D eF u n c i on a r i o a t u a li z a do r ) {
18 fo r ( F u nc i on a ri o f : this . f u n c i on a r i os ) {
19 f. aceita ( atualizador );
2 }
21 }
22 }
Código Java 4.93: Departamento.java
42 Faça uma classe para testar o atualizador salarial.
1 p u b li c c l a ss TestaAtualizadorSalarial {
2 p u b li c s t a ti c v o id m a i n ( S tr i n g [] a r gs ) {
3 List <Departamento > lista = ne w ArrayList <Departamento >();
4 Departamento departamento = ne w Departamento( " D e p a r ta m e n to 1 ");5 Gerente gerente = ne w Gerente(" G e r e nt e 1 " , 1 5 , "1234" );
6 Telefonista telefonista = ne w Telefonista("Telefonista" , 1 , 2 ) ;
116 www.k19.com.br
5/12/2018 k19 k51 Design Patterns Em Java - slidepdf.com
http://slidepdf.com/reader/full/k19-k51-design-patterns-em-java-55a4d0eeec4bf 121/121
117 P ADRÕES COMPORTAMENTAIS
7 d ep ar ta me nt o .g et Fu nc io na ri os () . add ( ge re nt e) ;
8 d ep ar ta me nt o .g et Fu nc io na ri os () . add ( te le fo ni st a );
9
1 lista .add ( departamento );
11
12 Departamento departamento2 = ne w Departamento( " D e p a r ta m e n to 2 ") ;13 Gerente gerente2 = ne w Gerente(" G e r e nt e 2 " , 1 8 , "1234" );
14 Gerente gerente3 = ne w Gerente(" G e r e nt e 3 " , 1 8 , "1234" );
15 Telefonista telefonista2 = ne w Telefonista("Telefonista2" , 1 2 , 1 );
16 d ep ar ta me nt o2 . ge tF un ci on ar io s () . ad d( ge re nt e2 ) ;
17 d ep ar ta me nt o2 . ge tF un ci on ar io s () . ad d( ge re nt e3 ) ;
18 d ep ar ta me nt o2 . ge tF un ci on ar io s () . ad d( t el ef on is ta 2) ;
19
2 lista .add ( departamento2 );
21
22 A tu al iz ad or De Fu nc io na ri o a tu al iz ad or = ne w AtualizadorSalarial();
23
24 fo r ( D e pa r ta m en t o d : l i st a ) {
25 d. aceita ( atualizador );
26 }
27
28 fo r ( D e pa r ta m en t o d : l i st a ) {
29 fo r ( F u n c i on a r i o f : d . g e t F u nc i o n ar i o s ( ) ) {
3 System . out . println (" N om e : " + f . g e t No m e ( ) + " - S al ár io : " + f.←
getSalario());
31 }
32 }
33 }
34 }
Código Java 4.94: TestaAtualizadorSalarial.java
www.k19.com.br 117