Autor: Eduardo R. Carvalhoemail: [email protected]
Design PatternsGang of Four – Elements of
Reusable OO
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.
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)
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;
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.
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.
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 Colaboradores
As entidades envolvidas no padrão.
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.
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.
GOFPropósito
Criação Estrutura Comportamento
Escopo
Classe Factory Method Class AdapterInterpreter
Template Method
Objeto
Abstract Factory Object Adapter Chain of Responsibility
Builder Bridge Command
Prototype Composite Iterator
Singleton Decorator Mediator
Facade Memento
Flyweight Observer
Proxy State
Strategy
Visitor
Classificando os Patterns
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 objetos4. Controlar formas de operação5. Implementar uma extensão para a aplicação
Classificando os Patterns
GoF segundo Metsker
Intenção Padrões
Interfaces Adapter, Facede,Composite, Bridge
Responsabilidade Singleton, Observer, Mediator, Proxy, Chain of Repository, Flyweitght
Construção Builder, Factory Method, Abstract Factory, Prototype, Memento
Operações Template Method, State, Strategy, Command, Interpreter
Extensões Decorator, Iterator, Visitor
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.
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
Pattern Singleton1. public class SingletonImplementation {2. 3. private static SingletonImplementation instance;4. 5. /**6. * Creates a new SingletonImplementation object.7. */8. private SingletonImplementation () {9. // initialize all attributes. 10. }11. 12. /**13. * Retrieves Singleton Instance for SingletonImplementation 14. * @return SingletonImplementation singletonImplementation 15. */16. public synchronized static SingletonImplementation getInstance() { 17. if (instance == null) {18. instance = new SingletonImplementation ();19. }20. return instance ;21. } 22. }
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
1. SingletonImplementation singleton =
2. SingletonImplementation.getInstance();
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.
Singleton - Exemplo de Uso1. package br.com.framework;2. import java.io.IOException;3. import java.io.InputStream;4. import java.util.Properties;5. public class Configuration {6. 7. private static final String fileName = "application.properties";8. private Properties properties;
9. public Configuration() {10. loadConfiguration();11. }
12. public void loadConfiguration () {13. 14. InputStream in = Configuration.class15. .getClassLoader()16. .getResourceAsStream(fileName); 17. try {18. properties.load(in);19. } catch (IOException e) {20. // TODO21. } 22. }23.}
Singleton - Exemplo de Uso
Memória Heap
public void method1 {
Configuration config = new Configuration () ;
}
public void method2 {
Configuration config = new Configuration () ;
}
public void method3 {
Configuration config = new Configuration () ;
}
Configuration
Configuration Configuration
O que acontece toda vez
que o contrutor de
Configuration é Chamado ?
HEAP
Singleton Aplicado.1. public class Configuration {2. 3. private static final String fileName = "application.properties";4. private Properties properties;5. private static Configuration instance;6. 7. private Configuration() {8. loadConfiguration();9. }10. 11. public static synchronized Configuration getInstance () {12. if (instance == null) 13. instance = new Configuration();14. return instance;15. }16. 17. public void loadConfiguration () { 18. InputStream in = Configuration.class19. .getClassLoader()20. .getResourceAsStream(fileName); 21. try {22. properties.load(in);23. } catch (IOException e) {24. // TODO25. } 26. }27. }
Singleton - Exemplo de Uso
Memória Heap
public void method1 {
Configuration config = Configuration.getInstance () ;
}
public void method2 {
Configuration config = Configuration.getInstance () ;
}
public void method3 {
Configuration config = Configuration.getInstance () ;}
Configuration
O que Aconteceu .. ?
HEAP
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.
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.
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.
Pattern Factory Method
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.
Factory Method - Utilização Pratica
Vamos demonstrar a aplicabilidade do pattern Factory Method através de outro Pattern DAO (Data Access Object)
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.
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.
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
Exemplo de Utilização
DAO (Novamente !!!)
Exemplo de Utilização
Exemplo de Utilização1. public abstract class DAOAbstractFactory {
2. private static final String DAOTYPE = "ORACLE";3. 4. public static DAOAbstractFactory instance; 5. 6. private DAOAbstractFactory() {7. } 8. 9. public static synchronized DAOAbstractFactory getInstance() {10. 11. if (instance == null) 12. instance = new DAOOracleFactory();13. 14. return instance; 15. }16. public abstract IClienteDAO getClienteDAO() ; 17. 18.}
Exemplo de Utilizaçãopublic class DAOMySQLFactory extends DAOAbstractFactory { public DAOMySQLFactory() { }
public IClienteDAO getClienteDAO() { return new ClienteMySQLDAO(); }
}
public class DAOOracleFactory extends DAOAbstractFactory { public DAOOracleFactory() { }
public IClienteDAO getClienteDAO() { return new ClienteOracleDAO(); }
}
Exemplo de Utilizaçãopublic class ClienteOracleDAO implements IClienteDAO { public ClienteOracleDAO() { }
public void create() { }
public void update() { }
public void detele() { }}
public class ClienteMySQLDAO implements IClienteDAO { public ClienteMySQLDAO() { }
public void create() { }
public void update() { }
public void detele() { }}
public interface IClienteDAO {
public void create(); public void update(); public void detele();
}
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.
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 ]
Pattern Builder
Problema
O cliente precisa criar um objeto, porém, o processo de criação é complexo e pode variar.
Exemplo:
Cliente
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.
Pattern Builder
Cliente Funcionário(Diretor)
Equipe Rest.(Builder)
Faz o pedido
Pega o pedido
build
build
build
build
Pega o pedido
Pattern Builder – Diagrama Classe
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
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.
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 ]
Pattern Prototype
Problema Criar um objeto novo, mas aproveitar o estado previamente existente em outro
objeto
Pattern Prototype – Diagrama de Classe
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; }}
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.
1. public class Circulo implements Cloneable {2. private Ponto origem;3. private double raio;
4. public Object clone() {5. try {6. Circulo c = (Circulo)super.clone();7. c.origem = origem.clone(); //Ponto deve ser clonável!8. return c;9. } catch(CloneNotSupportedException e) {10. return null;11. }12. }
13.}
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.
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
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.
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 ]
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.
Pattern Adapter – Class Adapter
Pattern Adapter – Class Adapterpublic interface ITarget { public void operation();}
public class Adaptee { public Adaptee() { } public void adaptedOperation () { //executa alguma operação } }
public class Adapter extends Adaptee implements ITarget { public Adapter() { super(); }
public void operation() { super.adaptedOperation(); }}
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(); } }
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
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
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
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 ]
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.
Pattern Façade
Problema Para fazer o subsistema funcionar, há diversos controles a serem acionados...
Pattern FaçadePorém, uma camada intermediária pode delegar as
requisições as respectivas funções...
Pattern Façade - Diagrama
Pattern Façade – Exemplo
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.
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 deacoplamento desejado entre os sistemas.
A Façades mostrada como exemplo isola totalmente o cliente dos objetos
Facade f; // Obtem instancia ff.registrar("Zé", 123);
Outra versão com menor isolamento (requer que aplicação-cliente conheça objeto Cliente)
Cliente joao = Cliente.create("João", 15);f.registrar(joao); // método registrar(Cliente c)
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
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 ]
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.
Pattern Composite - Problema
Cliente precisa tratar de maneira uniforme objetos individuais e composições de objetos
Pattern Composite – Diagrama de Classe
Tratar grupos e indivíduos diferentes através de uma única interface
Pattern CompositeComponente.javapublic abstract class Componente { private String pn; public String getPn() { return pn; } public void setPn(String pn) { this.pn = pn; } public Componente(String pn) { setPn(pn); } public abstract void operacao();
public abstract void add(Componente comp);
public abstract Componente remove(int index);
public abstract Componente getFilho(int index);
public abstract int getComponenteCount();
}
Composite.javapublic class Composite extends Componente { private ArrayList<Componente> componenteList;
public Composite(String pn) { super(pn); componenteList = new ArrayList<Componente>(); } public void operacao() { System.out.println("PN "+ getPn() +
" composto por: "); for(int i = 0; i < getComponenteCount(); i++) { getFilho(i).operacao(); } } public void add(Componente comp) { componenteList.add(comp); } public Componente remove(int index) { return componenteList.remove(index); } public Componente getFilho(int index){ return componenteList.get(index); } public int getComponenteCount() { return componenteList.size(); } }
Pattern CompositeFolha.javapublic class Folha extends Componente { public Folha(String pn) { super(pn); }
public void operacao() { System.out.println(getPn()); } public void add(Componente comp){ } public Componente remove(int index){ return null; } public Componente getFilho(int index){ return null; } public int getComponenteCount() { return -1; }}
Cliente.javapublic class Cliente {
public static void main(String[] args) {
Folha a1 = new Folha("A1"); Folha a2 = new Folha("A2"); Folha a3 = new Folha("A3");
Composite c1 = new Composite("C1"); c1.add(a1); c1.add(a2);
Composite c2 = new Composite("C2"); c2.add(a3);
Composite c3 = new Composite("C3"); c3.add(c1); c3.add(c2);
c3.operacao(); } }
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 loopsinfinitos, já que Composite depende de implementações recursivas
Há várias estratégias de implementação
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
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
Pattern Bridge
Bridge
"Desacoplar uma abstração de sua implementação para que os dois possam variar
independentemente.” GoF
Pattern Bridge Necessidade de um driver
Exemplo: Implementações específicas para tratar diferentes mecanismos de persistência
Pattern BridgeMas herança complica a implementação
Pattern Bridge
Pattern Bridge – Diagrama de Classe
A Abstração define operações de nível mais elevado baseadas nas operações primitivas do Implementador
A interface Implementador define operações primitivas
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
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
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
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
Pattern Proxy – Diagrama de Classe
Objeto Desejado
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.
Pattern Proxy
public class Creso { ... Sujeito deusApolo = Fabrica.getSujeito(); deusApolo.operacao(); ...}
public class DeusApolo implements Sujeito { public Object operacao() { return coisaUtil; }}
public class Oraculo implements Sujeito { private DeusApolo real; public Object operacao() { cobraTaxa(); return real.operacao(); }}
public interface Sujeito { public Object operacao();}
Inacessível ao Cliente
Cliente comunica-se com Objetoatravés dessa classe
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
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
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
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
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.
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.
Decorator 1 Decorator 2 Decorator 3Componente
Final
Pattern Decorator - Class Diagram
Pattern Decorator - Code//Interface Componentepublic interface IComponent { public void operacao(); }
// Componente Concretopublic class ComponentA
implements IComponent{
public ComponentA() { }
public void operacao() { }
}
// Componente Concretopublic class ComponentB
implements IComponent{
public ComponentB() { }
public void operacao() { }
}
public abstract class Decorator implements IComponent {
private IComponent component; public Decorator(IComponent component) { this.component = component; }
public void operacao() { component.operacao(); }
}
public class ConcreteDecorator extends
Decorator { public ConcreteDecorator(IComponent
component) { super(component); } public void operacao() { // Pre Actions ... super.operacao(); // Pos Actions ... }}
Pattern Decorator - Codepublic class ConcreteDecoratorB extends
Decorator { public ConcreteDecoratorB(IComponent
component) { super(component); } public void operacao() { // Pre Actions ... super.operacao(); // Pos Actions ... } }
public class Client { public Client() { } public static void main(String[] args) { IComponent component = new ConcreteDecorator ( new ConcreteDecoratorB ( new ComponentA() ) )
; } }
ConcreteDecoratorB
ConcreteDecorator
ComponentAoperacao ()
operacao ()operacao ()cliente
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.
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
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:
Pattern Template Method - Estrutura
Pattern Template Method - Codepublic abstract class AbstractTemplateMethod{
public abstract void preAction (); public abstract void posAction (); public abstract void coreAction(); public void execute () { preAction (); coreAction(); posAction (); } }
public class Client { public void clientMethod() { AbstractTemplateMethod
template = new Operation(); template.execute(); } }
public class Operation extends AbstractTemplateMethod {
public void preAction() { System.out.println("PreAction"); }
public void posAction() { System.out.println("PosAction"); }
public void coreAction() { System.out.println("CoreAction"); }}
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());...
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.
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
Pattern Chain of Responsibility
Pattern Chain of Responsibility - Codepublic interface Processor { public void setNextProcessor(Processor processor); public Processor getNextProcessor(); public Object processRequest();
}
public class Client {
public void clientMethod () { ..... Processor p = .... Object obj = p.processRequest();
..... } }
public class ConcreteProcessorA 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; }}
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; }}
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
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.
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.
Strategy - Diagrama
Strategy – Diagrama de Seqüência
Baseado no Conteúdo definido no Contexto é determinado qual é a melhor Estratégia a ser utilizada
Strategy – Exemplo de Utilização
Cenário : Internacionalização de Impostos de uma Aplicação de Compras.
Strategy – Exemplo de Utilização
Cenário : Internacionalização de Impostos de uma Aplicação de Compras.
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.
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.
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.
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
Pattern Observer
ConcreteObserver.java
public class ConcreteObserver implements Observer { public void update(Observable o) { ObservableData data = (ObservableData) o; data.getData(); }}
ConcreteObserver.java
public class ObservableData extends Observable { private Object myData; public void setData(Object myData) { this.myData = myData; notify(); } public Object getData() { return myData(); }}
Observable.java
public class Observable { List observers = new ArrayList(); public void add(Observer o) { observers.add(o); } public void remove(Observer o) { observers.remove(o); } public void notify() { Iterator it = observers.iterator(); while(it.hasNext()) { Observer o = (Observer)it.next(); o.update(this); } }}
Observer.java
public interface Observer { public void update(Observable o);}
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
inundados de requisições ("tempestade de eventos")
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.
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
Pattern State Permitir um objeto alterar seu comportamento
quando seu estado interno mudar.
Ex: Conexão
fazAlgo()
fazAlgo()
fazAlgo()
Pattern State - Estrutura
Pattern StateConexao.javapublic class Conexao {
ArrayList<Estado> estados;
public Conexao() { estados = new ArrayList<Estado>(); estados.add(new Desconectado()); estados.add(new Conectado()); estados.add(new Transmitindo()); }
public void processa() { for(Estado estado : estados) { estado.fazAlgo(); } }
}
Estado.javapublic interface Estado { public void fazAlgo();}
Desconectado.javapublic class Desconectado implements Estado { public void fazAlgo() { // faz algo enquanto desconectado }}
Conectado.javapublic class Conectado implements Estado { public void fazAlgo() { // faz algo enquanto conectado }}
Transmitindo.javapublic class Transmitindo implements Estado { public void fazAlgo() { // faz algo enquanto transmitindo }}
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.
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
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.
Pattern Visitor – Diagrama de Classe
Pattern Visitor – Diagrama de Seqüência
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)