1. Design Patterns
Gang of Four – Elements of
Reusable OO
Autor: Eduardo R.
Carvalho
email: ercarval@gmail.com
2. Pattern - Definição
O que é um Padrão (Pattern) ?
Define padrão como uma solução permanente para um problema em um
contexto. Contexto é o ambiente , circunstancias, situação ou condições
interdependentes dentro do qual algo existe.
O que é uma Estratégia ?
- Os padrões são descritos em um nível alto de Abstração. Ao mesmo tempo cada
padrão inclui várias estratégias que fornecem detalhes de implementação em
diversos níveis de abstração.
- Os padrões estão descritos em um nível mais alto de abstração.
- Os padrões incluem a maioria das implementações recomendadas ou mais comuns
como estratégia.
- As estratégias fornecem um ponto de flexibilidade para cada padrão.Os
desenvolvedores descobrem ou inventam novas maneiras de implementar os
padrões.
- As estratégias promovem uma comunicação melhor, fornecendo nomes para
aspectos de níveis mais baixos de uma determinada solução.
3. Motivação para Adoção
O simples uso da OO não garante que obtenhamos
sistemas confiáveis, robustos, extensíveis e reutilizáveis.
O foco das metodologias de desenvolvimento está na
solução em si (o que e como) e não em suas justificativas
(porque).
É difícil compartilhar a experiência entre experts e
novatos (passagem de conhecimento)
4. Características de utilização
Descrever e justificar soluções para problemas
concretos e bem definidos (não são estratégias de
implementação);
Ser comprovados, isto é, devem ter sido
previamente experimentados e testados;
Tratar problema que ocorram em diferentes
contextos;
5. Características de utilização
Descrever relações entre conceitos, mecanismos e
estruturas existentes nos sistemas, seus pontos
fortes e fracos;
Capturar a evolução e aprimoramento das
soluções;
Geralmente utilizados em conjunto com outros
padrões, compondo linguagens de padrões.
6. Resultados obtidos
Permitem compartilhar experiências bem
sucedidas na resolução de problemas recorrentes;
Compõem um vocabulário de alto nível para
discussão de questões relativas ao projeto de
sistemas de software;
Permitem que os desenvolvedores concentrem
seus esforços nos aspectos inéditos do problema.
7. Como Descrever um Pattern
Item Descrição
Nome Todos Os Padrões tem um nome único que os identifica.
Intenção O propósito do Padrão.
Problema O problema que o padrão esta tentando resolver.
Solução Como o padrão prove uma solução para o problema no
contexto em que ele aparece.
Participantes e As entidades envolvidas no padrão.
Colaboradores
Conseqüências Conseqüências em utilizar o padrão. Investiga as forças
que nele interagem.
Implementação Como o padrão pode ser implementado.
8. Classificando os Patterns
O GOF Classifica os patterns de duas formas
Propósito
Padrões de Criação (Creational)
Abstract Factory, Builder, Factory Method, Prototype, Singleton.
Padrões de Estrutura (Structural)
Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy.
Padrões de Comportamento(Behavioral)
Chain of Responsability, Command, Interpreter, Iterator, Mediator, Memento,
Observer, State, Strategy, Template Method, Visitor.
Por Escopo
Classe ou objeto.
9. Classificando os Patterns
Propósito
GOF Criação Estrutura Comportamento
Interpreter
Classe Factory Method Class Adapter
Template Method
Abstract Factory Object Adapter Chain of Responsibility
Builder Bridge Command
Prototype Composite Iterator
Escopo Singleton Decorator Mediator
Objeto Facade Memento
Flyweight Observer
Proxy State
Strategy
Visitor
10. Classificando os Patterns
Metsker classifica os Patterns do GOF em 5 grupos, por
intenção (problema a ser solucionado):
1. Oferecer uma interface,
2. Atribuir uma responsabilidade,
3. Realizar a construção de classes ou objetos
4. Controlar formas de operação
5. Implementar uma extensão para a aplicação
12. Patterns de Criação
Singleton: Garantir que uma classe só tenha uma única instância, e prover um
ponto de acesso global a ela.
Factory Method: Definir uma interface para criar um objeto mas deixar que
subclasses decidam que classe instanciar.
Abstract Factory : Prover interface para criar famílias de objetos relacionados
ou dependentes sem especificar suas classes concretas
Builder : Separar a construção de objeto complexo da representação para criar
representações diferentes com mesmo processo.
Prototype : Especificar tipos a criar usando uma instância como protótipo e criar
novos objetos ao copiar este protótipo.
13. Pattern Singleton
Intenção: Você deseja ter somente um objeto de uma classe, mas não existe
nenhum objeto global que controle a instanciação deste objeto
Problema: Vários objetos Clientes deferentes precisam se referir ao mesmo objeto
e voce deseja assegurar que não terá mais de um deles.
Solução: Garantir a existência de uma única instância para este objeto.
Participantes: Clientes que criam uma instancia da classe Singleton tão-somente
por meio de um método getInstance().
Conseqüências : Clientes não precisam preocupar-se com a possibilidade ou não
de uma instancia da classe Singleton existir. Isso é controlado pela própria
classe Singleton
14. Pattern Singleton
§ public class SingletonImplementation {
§
§ private static SingletonImplementation instance;
§
§ /**
§ * Creates a new SingletonImplementation object.
§ */
§ private SingletonImplementation () {
§ // initialize all attributes.
§ }
§
§ /**
§ * Retrieves Singleton Instance for SingletonImplementation
§ * @return SingletonImplementation singletonImplementation
§ */
§ public synchronized static SingletonImplementation getInstance() {
§ if (instance == null) {
§ instance = new SingletonImplementation ();
§ }
§ return instance ;
§ }
§ }
15. Diagrama
O Cliente nunca terá acesso ao construtor da classe Singleton, somente ao
método getInstance que garantirá uma única instancia desta classe.
Exemplo de um metodo cliente de Singleton
4. SingletonImplementation singleton =
5. SingletonImplementation.getInstance();
16. Singleton - Exemplo de Uso
Uma das Utilizações do Pattern Singleton seria
para uma Classe de Configuração de uma
aplicação.
Não há necessidade de criar varias instancias de uma
classe de configuração.
Vamos Olhar a Classe a Seguir e verificar como ficaria
a memoria Heap com varias chamadas a Classe
Configuration.
17. Singleton - Exemplo de Uso
§ package br.com.framework;
§ import java.io.IOException;
§ import java.io.InputStream;
§ import java.util.Properties;
§ public class Configuration {
§
§ private static final String fileName = "application.properties";
§ private Properties properties;
§ public Configuration() {
§ loadConfiguration();
§ }
§ public void loadConfiguration () {
§
§ InputStream in = Configuration.class
§ .getClassLoader()
§ .getResourceAsStream(fileName);
§ try {
§ properties.load(in);
§ } catch (IOException e) {
§ // TODO
§ }
§ }
§ }
18. Singleton - Exemplo de Uso
Memória Heap HEAP
Configuration Configuration
public void method1 {
Configuration
Configuration config = new Configuration () ;
}
public void method2 {
Configuration config = new Configuration () ;
}
O que acontece toda vez
public void method3 {
que o contrutor de
Configuration config = new Configuration () ; Configuration é Chamado ?
}
20. Singleton - Exemplo de Uso
Memória Heap HEAP
Configuration
public void method1 {
Configuration config = Configuration.getInstance () ;
}
public void method2 {
Configuration config = Configuration.getInstance () ;
}
public void method3 { O que Aconteceu .. ?
Configuration config = Configuration.getInstance () ;
}
21. Patterns de Criação
Singleton: Garantir que uma classe só tenha uma única instância, e prover um
ponto de acesso global a ela.
Factory Method: Definir uma interface para criar um objeto mas deixar que
subclasses decidam que classe instanciar.
Abstract Factory : Prover interface para criar famílias de objetos relacionados
ou dependentes sem especificar suas classes concretas
Builder : Separar a construção de objeto complexo da representação para criar
representações diferentes com mesmo processo.
Prototype : Especificar tipos a criar usando uma instância como protótipo e criar
novos objetos ao copiar este protótipo.
22. Pattern Factory Method
Intenção : Definir uma interface para criar um objeto, deixando, porem que as
subclasses decidam qual classe instanciar. Delegar a instanciação para as
subclasses.
Problema: Uma classe precisa de instanciar uma derivação de uma outra mas
não sabe qual. O FactoryMethod permite que uma classe derivada tome esta
decisão.
Solução: Uma classe derivada decide qual classe instanciar e o modo como
instanciá-la.
Participantes: Produto é a interface para o tipo de objeto que o Factory Method
cria. Gerador é a interface que decide o FactoryMethod.
Conseqüências: Clientes precisam especificar a classe Gerador para definir uma
classe ProdutoConcreto particular.
23. Pattern Factory Method
É uma interface para instanciação de objetos que mantém
isoladas as classes concretas usadas da requisição da
criação destes objetos.
• Separa assim:
Uma “família” de classes dotadas da mesma interface
(“produtos”); e
Uma classe (“fábrica”) que possui um método especial (o
factory method) que cria tais objetos.
25. Factory Method
Discas de implementação:
Existem algumas variações do Padrão Factory Method. Uma classe “fabrica” pode
não ter nenhuma sub classe e ter nela mesmo métodos simples concretos que
criam objetos. Esta variação é comum e bem discutida nos refactorings “Replace
Constructor with Creation Methods” e “Move Creation Knowledge to Factory”.
Se a Intenção é apenas centralizar a instanciação, é recomendável um simples
método static que retorna um novo objeto. Se deseja adiar a escolha do tipo do
objeto a ser criado para o momento de execução, podemos definir métodos não
estáticos e redefini-los de acordo com o tipo do objeto a ser criado.
26. Factory Method - Utilização Pratica
Vamos demonstrar a aplicabilidade do pattern Factory Method através de outro
Pattern DAO (Data Access Object)
27. Patterns de Criação
Singleton: Garantir que uma classe só tenha uma única instância, e prover um
ponto de acesso global a ela.
Factory Method: Definir uma interface para criar um objeto mas deixar que
subclasses decidam que classe instanciar.
Abstract Factory : Prover interface para criar famílias de objetos relacionados
ou dependentes sem especificar suas classes concretas
Builder : Separar a construção de objeto complexo da representação para criar
representações diferentes com mesmo processo.
Prototype : Especificar tipos a criar usando uma instância como protótipo e criar
novos objetos ao copiar este protótipo.
28. Abstract Factory
Intenção: Você deseja ter famílias ou conjuntos de objetos para
clientes (ou casos) particulares.
Problema: Famílias de objetos relacionados precisam ser
instanciadas.
Solução: Coordenar a criação de famílias de objetos. Esse
procedimento fornece uma maneira de remover as regras sobre
como realizar a instanciação para fora do objeto cliente que está
usando esses objetos criados.
Participantes: O Abstract Factory define a interface para o modo
como cada membro da família requerida de objetos. Tipicamente,
cada uma é gerada tendo sua própria e única FabricaConcreta.
Conseqüências: O padrão isola as regras referentes a quais objetos
usar da lógica de como utilizá-los.
29. Abstract Factory
Criar uma família de objetos relacionados sem conhecer suas classes concretas
Uma hierarquia que encapsule: várias plataformas e a construção de uma suite de produtos
32. Exemplo de Utilização
§ public abstract class DAOAbstractFactory {
§ private static final String DAOTYPE = "ORACLE";
§
§ public static DAOAbstractFactory instance;
§
§ private DAOAbstractFactory() {
§ }
§
§ public static synchronized DAOAbstractFactory getInstance() {
§
§ if (instance == null)
§ instance = new DAOOracleFactory();
§
§ return instance;
§ }
§ public abstract IClienteDAO getClienteDAO() ;
§
§ }
33. Exemplo de Utilização
public class DAOMySQLFactory public class DAOOracleFactory
extends DAOAbstractFactory { extends DAOAbstractFactory {
public DAOMySQLFactory() { public DAOOracleFactory() {
} }
public IClienteDAO getClienteDAO() { public IClienteDAO getClienteDAO() {
return new ClienteMySQLDAO(); return new ClienteOracleDAO();
} }
} }
34. Exemplo de Utilização
public class ClienteOracleDAO public class ClienteMySQLDAO
implements IClienteDAO { implements IClienteDAO {
public ClienteOracleDAO() { public ClienteMySQLDAO() {
} }
public void create() { public void create() {
} }
public void update() { public void update() {
} }
public void detele() { public void detele() {
} }
} }
public interface IClienteDAO {
public void create();
public void update();
public void detele();
}
35. Patterns de Criação
Singleton: Garantir que uma classe só tenha uma única instância, e prover um
ponto de acesso global a ela.
Factory Method: Definir uma interface para criar um objeto mas deixar que
subclasses decidam que classe instanciar.
Abstract Factory : Prover interface para criar famílias de objetos relacionados
ou dependentes sem especificar suas classes concretas
Builder : Separar a construção de objeto complexo da representação para criar
representações diferentes com mesmo processo.
Prototype : Especificar tipos a criar usando uma instância como protótipo e criar
novos objetos ao copiar este protótipo.
36. Pattern Builder
Builder
"Separar a construção de um objeto complexo de sua
representação para que o mesmo processo de
construção possa criar representações diferentes.“
[ GoF ]
37. Pattern Builder
Problema
O cliente precisa criar um objeto, porém, o processo de criação é complexo
e pode variar.
Exemplo:
Cliente
38. Pattern Builder
Solução
Separar a construção de sua representação assim como a construção possa criar
diferentes representações.
No exemplo dado:
Lanches infantis, geralmente, consistem de um item principal, um
acompanhamento, uma bebida e um brinquedo (ex, um hamburger, fritas,
guaraná e um dinossauro).
Notar que pode haver variações no conteúdo do lanche, mas o processo de
construção é o mesmo. Mesmo que o cliente peça um hamburger, cheeseburger
ou chicken, o processo é o mesmo.
Um funcionário junto ao caixa gerencia a equipe para "construir" o lanche com
um item principal, um acompanhamento, uma bebida e um brinquedo.
O mesmo processo é usado em diversos restaurantes.
39. Pattern Builder
Cliente Funcionário Equipe Rest.
(
(Diretor) (
(Builder)
Faz o pedido
build
build
build
build
Pega o pedido
Pega o pedido
41. Pattern Builder – Quando Usar ?
Quando Usar ?
Builder permite que uma classe se preocupe com apenas uma parte da
construção de um objeto. É útil em algoritmos de construção complexos
Use-o quando o algoritmo para criar um objeto complexo precisar ser
independente das partes que compõem o objeto e da forma como o
objeto é construído
Builder também suporta substituição dos construtores, permitindo que a
mesma interface seja usada para construir representações diferentes dos
mesmos dados
Use quando o processo de construção precisar suportar representações
diferentes do objeto que está sendo construído
42. Patterns de Criação
Singleton: Garantir que uma classe só tenha uma única instância, e prover um
ponto de acesso global a ela.
Factory Method: Definir uma interface para criar um objeto mas deixar que
subclasses decidam que classe instanciar.
Abstract Factory : Prover interface para criar famílias de objetos relacionados
ou dependentes sem especificar suas classes concretas
Builder : Separar a construção de objeto complexo da representação para criar
representações diferentes com mesmo processo.
Prototype : Especificar tipos a criar usando uma instância como protótipo e criar
novos objetos ao copiar este protótipo.
43. Pattern Prototype
Prototype
"Especificar os tipos de objetos a serem criados
usando uma instância como protótipo e criar
novos objetos ao copiar este protótipo.” [ GoF ]
46. Pattern Prototype – Exemplo
O Pattern Prototype é implementado pela especificação do JSE através da Interface Cloneable.
Object.clone() é um ótimo exemplo de Prototype em Java
Circulo c = new Circulo(4, 5, 6);
Circulo copia = (Circulo) c.clone();
Se o objeto apenas contiver tipos primitivos em seus campos de dados, é preciso
declarar que a classe implementa Cloneable
sobrepor clone() da seguinte forma:
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
47. Pattern Prototype – Exemplo
Se o objeto contiver campos de dados que são
referências a objetos, é preciso fazer cópias desses
objetos também.
§ public class Circulo implements Cloneable {
§ private Ponto origem;
§ private double raio;
§ public Object clone() {
§ try {
§ Circulo c = (Circulo)super.clone();
§ c.origem = origem.clone(); //Ponto deve ser clonável!
§ return c;
§ } catch(CloneNotSupportedException e) {
§ return null;
§ }
§ }
§ }
48. Pattern Prototype - Resumo
O padrão Prototype permite que um cliente crie novos
objetos ao copiar objetos existentes
Uma vantagem de criar objetos deste modo é poder
aproveitar o estado existente de um objeto
Object.clone() pode ser usado como implementação do
Prototype pattern em Java mas é preciso lembrar que ele
só faz cópias rasas: é preciso copiar também cada objeto
membro e seus campos recursivamente.
49. Patterns Estruturais
Adapter: Converter a interface de uma classe em outra interface esperada pelos clientes.
Façade: Oferecer uma interface única de nível mais elevado para um conjunto de interfaces de um
subsistema.
Composite: Permitir o tratamento de objetos individuais e composições desses objetos de maneira
uniforme.
Bridge: Desacoplar uma abstração de sua implementação para que os dois possam variar
independentemente.
Proxy: Prover um substituto ou ponto através do qual um objeto possa controlar o acesso a outro.
Flyweight: Usar compartilhamento para suportar eficientemente grandes quantidades de objetos
complexos.
Decorator: Anexar responsabilidades adicionais a um objeto dinamicamente
50. Pattern Adapter
Intenção: Casar um objeto existente, fora de seu controle, com
uma interface particular.
Problema: Um Sistema possui dados e comportamento correto
mas interface inadequada. Ele é tipicamente usado quando você
tem que fazer algo derivar de sua classe abstrata que estamos
definindo ou que já esta definida.
Solução: O Adapter fornece um empacotador com a interface
desejada.
Participantes: A classe Adapter ajusta a interface de uma classe
Adaptada para casar com a classe Alvo derivada de Adapter. Isso
possibilita ao cliente usar a classe Adaptada como se fosse um tipo
de Alvo.
Conseqüências: O Padrão Adapter possibilita que objetos
preexistentes caibam em novas estruturas de classes sem ser
limitados por suas interfaces.
51. Pattern Adapter – Diagrama de Classe
Converter a interface de uma classe em outra interface esperada pelos clientes. Adapter
permite a comunicação entre classes que não poderiam trabalhar juntas devido à
incompatibilidade de suas interfaces.“ [ GoF ]
52. Pattern Adapter
O Pattern Adapter é dividido em dois Patters:
Object Adapter: é O pattern demonstrado
anteriormente , uma vez que se baseia em um objeto
(objeto adaptador) contendo um outro (objeto
adaptado).
Class Adapter: Uma maneira de implementar o padrão
através de herança múltipla.
54. Pattern Adapter – Class Adapter
public interface ITarget { public class Adapter extends Adaptee
public void operation(); implements ITarget {
} public Adapter() {
super();
public class Adaptee { }
public Adaptee() {
} public void operation() {
super.adaptedOperation();
public void adaptedOperation () { }
//executa alguma operação }
}
} public class Client {
private ITarget iTarget;
public Client() {
// Poderia ser uma fabrica.
iTarget = new Adapter();
}
// getter e setters..comentadops
public static void main (String[] args) {
Client client = new Client ();
client.getITarget().operation();
}
}
55. Pattern Adapter
Quando Usar ?
Sempre que for necessário adaptar uma interface para um
cliente
Class Adapter
Quando houver uma interface que permita a implementação
estática
Object Adapter
Quando menor acoplamento for desejado
Quando o cliente não usa uma interface Java ou classe abstrata
que possa ser estendida
56. Pattern Adapter
Padrões semelhantes ou relacionados
Bridge
Possui estrutura similar mas tem outra finalidade: separar uma interface
de sua implementação para que possam ser alteradas
independentemente
Adapter serve para alterar a interface de um objeto existente
Decorator
Acrescenta funcionalidade a um objeto sem alterar sua interface (mais
transparente)
Proxy
Representa outro objeto sem mudar sua interface
57. Patterns Estruturais
Adapter: Converter a interface de uma classe em outra interface esperada pelos clientes.
Façade: Oferecer uma interface única de nível mais elevado para um conjunto de interfaces de um
subsistema.
Composite: Permitir o tratamento de objetos individuais e composições desses objetos de maneira
uniforme.
Bridge: Desacoplar uma abstração de sua implementação para que os dois possam variar
independentemente.
Proxy: Prover um substituto ou ponto através do qual um objeto possa controlar o acesso a outro.
Flyweight: Usar compartilhamento para suportar eficientemente grandes quantidades de objetos
complexos.
Decorator: Anexar responsabilidades adicionais a um objeto dinamicamente
58. Pattern Façade
Façade
"Oferecer uma interface única para um conjunto de
interfaces de um subsistema. Façade define uma
interface de nível mais elevado que torna o subsistema
mais fácil de usar.”
[ GoF ]
59. Pattern Façade
Intenção: Você deseja simplificar o uso de um sistema existente.
Precisa definir sua própria interface.
Problema: Você deseja utilizar somente um subconjunto de um
sistema complexo. Ou interagir com o sistema de uma maneira
particular
Solução: O Façade Apresenta uma nova interface para o cliente
usar o sistema existente
Participantes: Ele apresenta uma interface especifica para o
cliente o que torna o sistema mais fácil de ser utilizado.
Conseqüências: O Padrão simplifica o uso do sistema requerido.
64. Pattern Façade – Quando Usar
Sempre que for desejável criar uma interface para um
conjunto de objetos com o objetivo de facilitar o uso da
aplicação
Permite que objetos individuais cuidem de uma única
tarefa, deixando que a fachada se encarregue de
divulgar as suas operações.
65. Pattern Façade – Nível de Acoplamento
Façades podem oferecer maior ou menor isolamento
entre aplicação cliente e objetos.
Nível ideal deve ser determinado pelo nível de
acoplamento desejado entre os sistemas.
A Façades mostrada como exemplo isola totalmente o
cliente dos objetos
Facade f; // Obtem instancia f
f.registrar("Zé", 123);
Outra versão com menor isolamento (requer que aplicação-
c
cliente conheça objeto Cliente)
Cliente joao = Cliente.create("João", 15);
f
f.registrar(joao); // método registrar(Cliente c)
66. Patterns Estruturais
Adapter: Converter a interface de uma classe em outra interface esperada pelos clientes.
Façade: Oferecer uma interface única de nível mais elevado para um conjunto de interfaces de um
subsistema.
Composite: Permitir o tratamento de objetos individuais e composições desses objetos de maneira
uniforme.
Bridge: Desacoplar uma abstração de sua implementação para que os dois possam variar
independentemente.
Proxy: Prover um substituto ou ponto através do qual um objeto possa controlar o acesso a outro.
Flyweight: Usar compartilhamento para suportar eficientemente grandes quantidades de objetos
complexos.
Decorator: Anexar responsabilidades adicionais a um objeto dinamicamente
67. Pattern Composite
Composite
"Compor objetos em estruturas de árvore para representar
hierarquias todo-parte. Composite permite que clientes
tratem objetos individuais e composições de objetos de
maneira uniforme.” [ GoF ]
68. Pattern Composite
São comuns as situações onde temos que lidar com
uma estrutura de elementos agrupada
hierarquicamente (não como meras coleções).
• Composições podem cumprir com este requisito e
ainda permitir:
o tratamento da composição como um todo;
ignorar as diferenças entre composições e elementos individuais;
adição transparente de novos tipos a hierarquia;
simplificação do cliente.
69. Pattern Composite - Problema
Cliente precisa tratar de
maneira uniforme objetos
individuais e composições
de objetos
70. Pattern Composite – Diagrama de Classe
Tratar grupos e
indivíduos diferentes
através de uma única
interface
71. Pattern Composite
Componente.java
public abstract class Componente { Composite.java
public class Composite extends Componente {
private String pn;
private ArrayList<Componente> componenteList;
public String getPn() {
return pn; public Composite(String pn) {
} super(pn);
componenteList = new ArrayList<Componente>();
public void setPn(String pn) { }
this.pn = pn;
} public void operacao() {
System.out.println("PN "+ getPn() +
public Componente(String pn) { " composto por: ");
setPn(pn); f
for(int i = 0; i < getComponenteCount(); i++) {
} getFilho(i).operacao();
}
}
public abstract void operacao();
public void add(Componente comp) {
public abstract void add(Componente comp); componenteList.add(comp);
}
public abstract Componente remove(int public Componente remove(int index) {
index);
return componenteList.remove(index);
}
public abstract Componente getFilho(int public Componente getFilho(int index){
index);
return componenteList.get(index);
}
public abstract int getComponenteCount();
public int getComponenteCount() {
return componenteList.size();
} }
}
72. Pattern Composite
Folha.java Cliente.java
public class Folha extends Componente { public class Cliente {
public Folha(String pn) {
super(pn); public static void main(String[] args) {
}
Folha a1 = new Folha("A1");
public void operacao() { Folha a2 = new Folha("A2");
System.out.println(getPn()); Folha a3 = new Folha("A3");
}
Composite c1 = new Composite("C1");
public void add(Componente comp){ c1.add(a1);
}
c1.add(a2);
public Componente remove(int index){
return null; Composite c2 = new Composite("C2");
} c2.add(a3);
public Componente getFilho(int index){ Composite c3 = new Composite("C3");
return null; c3.add(c1);
}
c3.add(c2);
public int getComponenteCount() {
return -1; c3.operacao();
} }
}
}
73. Pattern Composite – Quando Usar ?
Sempre que houver necessidade de tratar um
conjunto como um indivíduo
Funciona melhor se relacionamentos entre os objetos
for uma árvore
Caso o relacionamento contenha ciclos, é preciso
tomar precauções adicionais para evitar loops
infinitos, já que Composite depende de
implementações recursivas
Há várias estratégias de implementação
74. Pattern Composite – Dicas
Questões importantes para implementação
Referências explícitas ao elemento pai
getParent()
Direção do relacionamento
Filhos conhecem pai? Pai conhece filhos?
Compartilhamento
Risco de guardar pais múltiplos (ciclos)
Operações add() e remove() nos filhos
getComponent() para saber se é folha ou composite
Quem deve remover componentes?
Composite destroi seus filhos quando é destruído?
Cascade-delete e proteção contra folhas soltas
75. Patterns Estruturais
Adapter: Converter a interface de uma classe em outra interface esperada pelos clientes.
Façade: Oferecer uma interface única de nível mais elevado para um conjunto de interfaces de um
subsistema.
Composite: Permitir o tratamento de objetos individuais e composições desses objetos de maneira
uniforme.
Bridge: Desacoplar uma abstração de sua implementação para que os dois possam variar
independentemente.
Proxy: Prover um substituto ou ponto através do qual um objeto possa controlar o acesso a outro.
Flyweight: Usar compartilhamento para suportar eficientemente grandes quantidades de objetos
complexos.
Decorator: Anexar responsabilidades adicionais a um objeto dinamicamente
76. Pattern Bridge
Bridge
"Desacoplar uma abstração de sua implementação
para que os dois possam variar
independentemente.”
GoF
77. Pattern Bridge
Necessidade de um driver
Exemplo:
Implementações específicas para tratar
diferentes mecanismos de persistência
80. Pattern Bridge – Diagrama de Classe
A Abstração define operações de A interface Implementador define
nível mais elevado baseadas nas operações primitivas
operações primitivas do
Implementador
81. Pattern Bridge – Quando Usar
Quando for necessário evitar uma ligação permanente entre a
interface e implementação
Quando alterações na implementação não puderem afetar clientes
Quando tanto abstrações como implementações precisarem ser
capazes de suportar extensão através de herança
Quando implementações são compartilhadas entre objetos
desconhecidos do cliente
82. Pattern Bridge - Conseqüências
Detalhes de implementação totalmente
inaccessíveis aos clientes
Eliminação de dependências em tempo de
compilação das implementações
Implementação da abstração pode ser
configurada em tempo de execução
Exemplo de bridge: drivers JDBC
83. Patterns Estruturais
Adapter: Converter a interface de uma classe em outra interface esperada pelos clientes.
Façade: Oferecer uma interface única de nível mais elevado para um conjunto de interfaces de um
subsistema.
Composite: Permitir o tratamento de objetos individuais e composições desses objetos de maneira
uniforme.
Bridge: Desacoplar uma abstração de sua implementação para que os dois possam variar
independentemente.
Proxy: Prover um substituto ou ponto através do qual um objeto possa controlar o acesso a outro.
Flyweight: Usar compartilhamento para suportar eficientemente grandes quantidades de objetos
complexos.
Decorator: Anexar responsabilidades adicionais a um objeto dinamicamente
84. Pattern Proxy – Problema
Sistema quer utilizar um determinado objeto...
Mas ele não está disponível (remoto, inaccessível, etc)
Solução: arranjar um intermediário que saiba se comunicar com ele
eficientemente
86. Pattern Proxy - Estrutura
Cliente usa intermediário em vez de sujeito real
Intermediário suporta a mesma interface que sujeito real
Intermediário contém uma referência para o sujeito real
e repassa chamadas, possivelmente, acrescentando
informações ou filtrando dados no processo.
87. Pattern Proxy
public class Creso {
...
Sujeito deusApolo = Fabrica.getSujeito();
deusApolo.operacao();
...
}
Inacessível ao Cliente public class DeusApolo implements Sujeito {
public Object operacao() {
return coisaUtil;
}
}
public class Oraculo implements Sujeito {
private DeusApolo real; Cliente comunica-se com Objeto
public Object operacao() { através dessa classe
cobraTaxa();
return real.operacao();
}
}
public interface Sujeito {
public Object operacao();
}
88. Pattern Proxy – Quando Usar ?
A aplicação mais comum é em objetos distribuídos
Exemplo: RMI (e EJB)
O Stub é proxy do cliente para o objeto remoto
O Skeleton é parte do proxy: cliente remoto chamado pelo Stub
89. Pattern Proxy – Prós X Contras
Vantagens
Transparência: mesma sintaxe usada na comunicação entre o
cliente e sujeito real é usada no proxy
Permite o tratamento inteligente dos dados no cliente
Desvantagens
Possível impacto na performance
Transparência nem sempre é 100% (fatores externos como
queda da rede podem tornar o proxy inoperante ou
desatualizado
90. Patterns Estruturais
Adapter: Converter a interface de uma classe em outra interface esperada pelos clientes.
Façade: Oferecer uma interface única de nível mais elevado para um conjunto de interfaces de um
subsistema.
Composite: Permitir o tratamento de objetos individuais e composições desses objetos de maneira
uniforme.
Bridge: Desacoplar uma abstração de sua implementação para que os dois possam variar
independentemente.
Proxy: Prover um substituto ou ponto através do qual um objeto possa controlar o acesso a outro.
Flyweight: Usar compartilhamento para suportar eficientemente grandes quantidades de objetos
complexos.
Decorator: Anexar responsabilidades adicionais a um objeto dinamicamente
91. Pattern Decorator
Decorator
"Anexar responsabilidades adicionais a um objeto
dinamicamente. Decorators oferecem uma alternativa
flexível ao uso de herança para estender uma
funcionalidade.” GoF
92. Decorator
Intenção : Anexar dinamicamente responsabilidades a um objeto.
Problema: O objeto que deseja utilizar realiza as funções básicas que você quer.
Entretanto, pode ser necessário acrescentar alguma funcionalidade adicional a
ele, ocorrendo antes ou após a funcionalidade básica do objeto.
Solução: Permite estender a funcionalidade de um objeto sem recorrer à
subclassificação.
Participantes: ComponenteConcreto é a classe que tem a função a ela
adicionada pelas classes Decorator. Algumas vezes as classes dela derivadas são
usadas para fornecer a funcionalidade central e , neste caso a
ComponenteConcreto não é mais concreta, mas preferivelmente abstrata, ela
define a interface a ser utilizada por todas essas classes.
Conseqüências: A Funcionalidade a ser adicionada reside em pequenos objetos.
A Vantagem esta na capacidade dinâmica de adicionar esta função antes ou
depois na funcionalidade na ComponenteConcreto.
93. Decorator
Atribui responsabilidades adicionais a um objeto dinamicamente.
Fornece uma alternativa flexível à utilização de subclasses para a
extensão de funcionalidades.
Este Pattern permite cadeia de objetos que inicia com os
Decorators ( responsáveis pelas novas funcionalidades ) e encerra
com o objeto final.
Componente
Decorator 1 Decorator 2 Decorator 3
Final
95. Pattern Decorator - Code
//Interface Componente public abstract class Decorator
public interface IComponent { implements IComponent {
public void operacao();
private IComponent component;
}
public Decorator(IComponent component) {
// Componente Concreto this.component = component;
public class ComponentA }
implements IComponent{
public ComponentA() { public void operacao() {
} component.operacao();
}
public void operacao() {
} }
} public class ConcreteDecorator extends
// Componente Concreto Decorator {
public class ComponentB public ConcreteDecorator(IComponent
component) {
implements IComponent{
public ComponentB() { super(component);
}
}
public void operacao() {
// Pre Actions ...
public void operacao() {
} super.operacao();
// Pos Actions ...
}
}
}
96. Pattern Decorator - Code
public class ConcreteDecoratorB extends public class Client {
Decorator { public Client() {
}
public ConcreteDecoratorB(IComponent
component) { public static void main(String[] args) {
super(component);
} IComponent component =
new ConcreteDecorator (
public void operacao() { new ConcreteDecoratorB (
// Pre Actions ... new ComponentA() ) ) ;
super.operacao();
// Pos Actions ...
} }
} }
operacao ()
entA
pon
cliente () Co m
operacao () acao
ope r
ConcreteDecoratorB
ConcreteDecorator
97. Patterns Comportamentais
Interpreter : Dada uma linguagem, definir uma representação para sua gramática junto com um interpretador.
Template Method : Definir o esqueleto de um algoritmo dentro de uma operação, deixando alguns passos a serem
preenchidos pelas subclasses
Chain of Responsibility : Compor objetos em cascata para, através dela, delegar uma requisição até que um objeto
a sirva.
Command Encapsular : requisição como objeto, para clientes parametrizarem diferentes requisições, filas, e
suportar operações reversíveis
Iterator : Prover uma maneira de acessar elementos de um objeto agregado seqüencialmente sem expor sua
representação interna
Mediator : Definir um objeto que encapsula a forma como um conjunto de objetos interagem
Memento : Externalizar o estado interno de um objeto para que o objeto possa ter esse estado restaurado
posteriormente.
Observer : Definir uma dependência um-para-muitos entre objetos para que quando um objeto mudar de estado,
os seus dependentes sejam notificados e atualizados automaticamente
State : Permitir a um objeto alterar o seu comportamento quanto o seu estado interno mudar.
Strategy : Definir uma família de algoritmos, encapsular cada um, e fazê-los intercambiáveis.
Visitor : Representar uma operação a ser realizada sobre os elementos de uma estrutura de objetos.
98. Pattern Template Method
Template Method
"Definir o esqueleto de um algoritmo dentro de uma
operação, deixando alguns passos a serem preenchidos pelas subclasses. Template
Method permite que suas subclasses redefinam certos passos de um algoritmo
sem mudar sua estrutura.” GoF
99. Pattern Template Method
Problema : Definir a estrutura de um algoritmo, implementando a logica
comum e deixando passos para implementação por subclasses
Solução: Criar uma classe abstrata com o metodo concreto base e utilizar
metodos abstratos como ganchos para implementação na subclasses
Participantes:
Consequencia:
101. Pattern Template Method - Code
public abstract class AbstractTemplateMethod{ public class Operation extends
AbstractTemplateMethod {
public abstract void preAction ();
public abstract void posAction (); public void preAction() {
public abstract void coreAction(); System.out.println("PreAction");
}
public void execute () {
preAction (); public void posAction() {
coreAction(); System.out.println("PosAction");
posAction (); }
}
} public void coreAction() {
System.out.println("CoreAction");
}
public class Client { }
public void clientMethod() {
AbstractTemplateMethod
template = new Operation();
template.execute();
}
}
102. Pattern Template Method
O método Arrays.sort (java.util) é um bom exemplo de Template Method. Ele
recebe como parâmetro um objeto do tipo Comparator que implementa um
método compare(a, b) e utiliza-o para definir as regras de ordenação
public class MedeCoisas implements Comparator {
public int compare(Object o1, Object o2) {
Coisa c1 = (Coisa) o1;
Coisa c2 = (Coisa) o2;
if (c1.getID() > c2.getID()) return 1;
if (c1.getID() < c2.getID()) return -1;
if (c1.getID() == c2.getID()) return 0;
}
}
...
Coisa coisas[] = new Coisa[10];
coisas[0] = new Coisa(45);
coisas[1] = new Coisa(67);
...
Arrays.sort(coisas, new MedeCoisas());
...
103. Patterns Comportamentais
Interpreter : Dada uma linguagem, definir uma representação para sua gramática junto com um interpretador.
Template Method : Definir o esqueleto de um algoritmo dentro de uma operação, deixando alguns passos a serem
preenchidos pelas subclasses
Chaing of Repository : Compor objetos em cascata para, através dela, delegar uma requisição até que um objeto a
sirva.
Command Encapsular : requisição como objeto, para clientes parametrizarem diferentes requisições, filas, e
suportar operações reversíveis
Iterator : Prover uma maneira de acessar elementos de um objeto agregado seqüencialmente sem expor sua
representação interna
Mediator : Definir um objeto que encapsula a forma como um conjunto de objetos interagem
Memento : Externalizar o estado interno de um objeto para que o objeto possa ter esse estado restaurado
posteriormente.
Observer : Definir uma dependência um-para-muitos entre objetos para que quando um objeto mudar de estado,
os seus dependentes sejam notificados e atualizados automaticamente
State : Permitir a um objeto alterar o seu comportamento quanto o seu estado interno mudar.
Strategy : Definir uma família de algoritmos, encapsular cada um, e fazê-los intercambiáveis.
Visitor : Representar uma operação a ser realizada sobre os elementos de uma estrutura de objetos.
104. Pattern Chain of Responsibility
Chain of Responsibility
"Evita acoplar o remetente de uma requisição ao seu destinatário ao
dar a mais de um objeto a chance de servir a requisição. Compõe
os objetos em cascata e passa a requisição pela corrente até que
um objeto a sirva.” GoF
106. Pattern Chain of Responsibility - Code
public interface Processor { public class ConcreteProcessorA
public void setNextProcessor(Processor processor); implements Processor{
public Processor getNextProcessor(); private Processor sucessor;
public Object processRequest(); public Object processRequest() {
// any action
} return sucessor.processRequest();
}
public void setNextProcessor(
public class Client { Processor processor) {
sucessor = processor;
public void clientMethod () { }
..... public Processor getNextProcessor() {
Processor p = .... return sucessor;
Object obj = p.processRequest(); }
..... }
}
} public class ConcreteProcessorB
implements Processor{
private Processor sucessor;
public Object processRequest() {
// any action
return sucessor.processRequest();
}
public void setNextProcessor(
Processor processor) {
sucessor = processor;
}
public Processor getNextProcessor() {
return sucessor;
}
}
107. Pattern Chain of Responsibility
Estratégias de Implementação
Pode-se implementar um padrão de várias formas
diferentes. Cada forma é chamada de estratégia
Chain of Responsibility pode ser implementada com
estratégias que permitem maior ou menor
acoplamento entre os participantes
Usando delegação: cada participante conhece o seu
sucessor
Usando um mediador: só o mediador sabe quem é o
próximo participante da cadeia
108. Patterns Comportamentais
Interpreter : Dada uma linguagem, definir uma representação para sua gramática junto com um interpretador.
Template Method : Definir o esqueleto de um algoritmo dentro de uma operação, deixando alguns passos a serem
preenchidos pelas subclasses
Chaing of Repository : Compor objetos em cascata para, através dela, delegar uma requisição até que um objeto a
sirva.
Command Encapsular : requisição como objeto, para clientes parametrizarem diferentes requisições, filas, e
suportar operações reversíveis
Iterator : Prover uma maneira de acessar elementos de um objeto agregado seqüencialmente sem expor sua
representação interna
Mediator : Definir um objeto que encapsula a forma como um conjunto de objetos interagem
Memento : Externalizar o estado interno de um objeto para que o objeto possa ter esse estado restaurado
posteriormente.
Observer : Definir uma dependência um-para-muitos entre objetos para que quando um objeto mudar de estado,
os seus dependentes sejam notificados e atualizados automaticamente
State : Permitir a um objeto alterar o seu comportamento quanto o seu estado interno mudar.
Strategy : Definir uma família de algoritmos, encapsular cada um, e fazê-los intercambiáveis.
Visitor : Representar uma operação a ser realizada sobre os elementos de uma estrutura de objetos.
109. Strategy
Intenção : Permite a você utilizar regras de negócio ou algoritmos diferentes,
dependendo do contexto em que eles ocorrem.
Problema:A seleção de um algoritmo que precisa ser aplicado depende do cliente que faz
a solicitação ou dos dados que estão sendo operados. Se você dispõe de uma regra que
simplesmente não muda, não precisa de um padrão Strategy.
Solução: Separar a seleção de algoritmos da implementação destes. Permitir que a
seleção seja feita com base no contexto.
Participantes: O Strategy especifica como os diferentes algoritmos são utilizados.
As classes EstratégiasConcretas implementam esses diferentes algoritmos.
A classe Contexto usa a EstratégiaConcreta específica com uma referência do tipo Strategy. As
classes Strategy e Contexto interagem para implementar o algoritmo escolhido (algumas vezes
a classe Strategy deve questionar contexto). A classe contexto repassa pedidos de seu Cliente
para a Strategy.
Conseqüências: O padrão Strategy define uma família de algoritmos.
Os comandos switch e/ou condicionais podem ser eliminados.
Você deve invocar todos os algoritmos da mesma maneira (eles todos devem ter a mesma
interface). A interação entre as Classes EstratégiaConcreta e a Classe Contexto pode requerer a
adição de métodos do tipo obterEstado para a Classe Contexto.
111. Strategy – Diagrama de Seqüência
Baseado no Conteúdo definido no Contexto é determinado qual é a
melhor Estratégia a ser utilizada
112. Strategy – Exemplo de Utilização
Cenário : Internacionalização de Impostos de uma
Aplicação de Compras.
113. Strategy – Exemplo de Utilização
Cenário : Internacionalização de Impostos de uma
Aplicação de Compras.
114. Strategy – Exemplo de Utilização
Baseado no conteúdo contido no Documento de
Compra é determinada qual a estratégia de
calculo de Impostos. Pode ser utilizado também o
Pattern Factory Method para criar a instancia da
Estratégia Concreta.
115. Patterns Comportamentais
Interpreter : Dada uma linguagem, definir uma representação para sua gramática junto com um interpretador.
Template Method : Definir o esqueleto de um algoritmo dentro de uma operação, deixando alguns passos a serem
preenchidos pelas subclasses
Chaing of Repository : Compor objetos em cascata para, através dela, delegar uma requisição até que um objeto a
sirva.
Command Encapsular : requisição como objeto, para clientes parametrizarem diferentes requisições, filas, e
suportar operações reversíveis
Iterator : Prover uma maneira de acessar elementos de um objeto agregado seqüencialmente sem expor sua
representação interna
Mediator : Definir um objeto que encapsula a forma como um conjunto de objetos interagem
Memento : Externalizar o estado interno de um objeto para que o objeto possa ter esse estado restaurado
posteriormente.
Observer : Definir uma dependência um-para-muitos entre objetos para que quando um objeto mudar de estado,
os seus dependentes sejam notificados e atualizados automaticamente
State : Permitir a um objeto alterar o seu comportamento quanto o seu estado interno mudar.
Strategy : Definir uma família de algoritmos, encapsular cada um, e fazê-los intercambiáveis.
Visitor : Representar uma operação a ser realizada sobre os elementos de uma estrutura de objetos.
116. Observer
Intenção : Definir uma dependência de um para muitos entre os objetos, para
que quando um deles mudarem de estado todos os seus dependentes sejam
notificados e atualizados automaticamente.
Problema: Você precisa notificar uma lista variável de objetos de que um
evento ocorreu.
Solução:Os Observers delegam a responsabilidade de monitoração de um
evento a um Objeto Central: o “Subject”.
Participantes: O Subject conhecem seus Observers porque eles se registram
com ele.Ele deve notifica-los que o evento em questão ocorrer. Os Observers
são responsáveis por se registrar e obter informações do evento ocorrido.
Conseqüências: Subjects podem informar aos Observers eventos não relevantes
para este, no caso dos Observers interessados em um sub-conjunto de eventos
específicos.
117. Observer
Existem situações onde diversos objetos (p.e.
visualizações) devem representar um outro objeto
(p.e. dados).
Define uma relação de dependência 1:N de forma
que quando um certo objeto (assunto) tem seu
estado modificado os demais (observadores) são
notificados.
Possibilita baixo acoplamento entre os objetos
observadores e o assunto
119. ConcreteObserver.java Observable.java
public class ConcreteObserver public class Observable {
implements Observer { List observers = new ArrayList();
public void update(Observable o) { public void add(Observer o) {
ObservableData data = (ObservableData) o; observers.add(o);
data.getData(); }
public void remove(Observer o) {
}
observers.remove(o);
} }
public void notify() {
Iterator it = observers.iterator();
ConcreteObserver.java while(it.hasNext()) {
Observer o = (Observer)it.next();
public class ObservableData o.update(this);
extends Observable { }
private Object myData; }
public void setData(Object myData) { }
this.myData = myData;
notify();
Observer.java
}
public Object getData() {
public interface Observer {
return myData();
public void update(Observable o);
}
}
}
120. Pattern Observer – Pros e Contras
Vantagens
Tanto observadores quando sujeitos observados podem ser
reutilizados e ter sua interface e implementação alteradas sem
afetar o sistema
O acoplamento forte implicado pelo relacionamento
bidirecional é reduzido com o uso de interfaces e classes
abstratas
Desvantagens
O abuso pode causar sério impacto na performance.
Sistemas onde todos notificam todos a cada mudança ficam
i
inundados de requisições ("tempestade de eventos")
121. Patterns Comportamentais
Interpreter : Dada uma linguagem, definir uma representação para sua gramática junto com um interpretador.
Template Method : Definir o esqueleto de um algoritmo dentro de uma operação, deixando alguns passos a serem
preenchidos pelas subclasses
Chaing of Repository : Compor objetos em cascata para, através dela, delegar uma requisição até que um objeto a
sirva.
Command Encapsular : requisição como objeto, para clientes parametrizarem diferentes requisições, filas, e
suportar operações reversíveis
Iterator : Prover uma maneira de acessar elementos de um objeto agregado seqüencialmente sem expor sua
representação interna
Mediator : Definir um objeto que encapsula a forma como um conjunto de objetos interagem
Memento : Externalizar o estado interno de um objeto para que o objeto possa ter esse estado restaurado
posteriormente.
Observer : Definir uma dependência um-para-muitos entre objetos para que quando um objeto mudar de estado,
os seus dependentes sejam notificados e atualizados automaticamente
State : Permitir a um objeto alterar o seu comportamento quanto o seu estado interno mudar.
Strategy : Definir uma família de algoritmos, encapsular cada um, e fazê-los intercambiáveis.
Visitor : Representar uma operação a ser realizada sobre os elementos de uma estrutura de objetos.
122. Pattern State
State
“Permitir a um objeto alterar o seu comportamento
quanto o seu estado interno mudar. O objeto irá
aparentar mudar de classe.” GoF
123. Pattern State
Permitir um objeto alterar seu comportamento
quando seu estado interno mudar.
Conexão
Ex:
f
fazAlgo()
f
fazAlgo()
f
fazAlgo()
125. Pattern State
Desconectado.java
Conexao.java public class Desconectado implements Estado {
public class Conexao {
p
public void fazAlgo() {
ArrayList<Estado> estados;
// faz algo enquanto desconectado
}
p
public Conexao() { }
estados = new ArrayList<Estado>();
estados.add(new Desconectado());
estados.add(new Conectado()); Conectado.java
estados.add(new Transmitindo()); public class Conectado implements Estado {
}
p
public void fazAlgo() {
p
public void processa() {
// faz algo enquanto conectado
f
for(Estado estado : estados) { }
estado.fazAlgo(); }
}
}
Transmitindo.java
} public class Transmitindo implements Estado {
p
public void fazAlgo() {
Estado.java }
// faz algo enquanto transmitindo
public interface Estado {
public void fazAlgo(); }
}
126. Patterns Comportamentais
Interpreter : Dada uma linguagem, definir uma representação para sua gramática junto com um interpretador.
Template Method : Definir o esqueleto de um algoritmo dentro de uma operação, deixando alguns passos a serem
preenchidos pelas subclasses
Chaing of Repository : Compor objetos em cascata para, através dela, delegar uma requisição até que um objeto a
sirva.
Command Encapsular : requisição como objeto, para clientes parametrizarem diferentes requisições, filas, e
suportar operações reversíveis
Iterator : Prover uma maneira de acessar elementos de um objeto agregado seqüencialmente sem expor sua
representação interna
Mediator : Definir um objeto que encapsula a forma como um conjunto de objetos interagem
Memento : Externalizar o estado interno de um objeto para que o objeto possa ter esse estado restaurado
posteriormente.
Observer : Definir uma dependência um-para-muitos entre objetos para que quando um objeto mudar de estado,
os seus dependentes sejam notificados e atualizados automaticamente
State : Permitir a um objeto alterar o seu comportamento quanto o seu estado interno mudar.
Strategy : Definir uma família de algoritmos, encapsular cada um, e fazê-los intercambiáveis.
Visitor : Representar uma operação a ser realizada sobre os elementos de uma estrutura de objetos.
127. Pattern Visitor
Visitor
“Representar uma operação a ser realizada sobre os elementos de
uma estrutura de objetos. Visitor permite definir uma nova
operação sem mudar as classes dos elementos nos quais opera”
GOF
128. Pattern Visitor
Intenção: Promover fácil manutenabilidade em um determinadas
ações para uma família de Objetos. Centralizando o
comportamento permitindo a extensão desta sem alterar as
operações em si.
Problema: Permitir a criação de novas operações que atuam sobre
uma estrutura de objetos, sem a necessidade de alterar a sua
estrutura.
Solução: Crie uma classe separada para a operação (o Visitor). Os
objetos desta classe irão percorrer a estrutura apropriada no
sistema, executando a logica relacionada a cada objeto encontrado
de acordo com o seu tipo.
131. Pattern Visitor – Prós e Contras
Vantagens
Facilita a adição de novas operações
Agrupa operações relacionadas e separa operações não relacionadas: reduz
espalhamento de funcionalidades e embaralhamento
Desvantagens
Dá trabalho adicionar novos elementos na hierarquia: requer alterações em
todos os Visitors. Se a estrutura muda com frequência, não use!
Quebra de encapsulamento: métodos e dados usados pelo visitor têm de
estar acessíveis
Alternativas ao uso de visitor estendem OO
Aspectos (www.aspectj.org) e Hyperslices
(
(www.research.ibm.com/hyperspace)