Design Pattern
Visitor
Projeto de Sistemas de Software
Leandra Mara da Silva
Motivação
• Motivação para o trabalho
– Aprimorar conhecimentos de Projeto de Sistemas de
Software, realizando um estudo sobre os Padrões de Projeto
apresentados em [GoF].
• Objetivo
– Fornecer uma visão geral sobre o padrão Visitor.
© LES/PUC-Rio
Padrão Visitor (Visitante)
Visitor
• Classificação
– Comportamental de objeto: mostra como objetos podem
cooperar para executar uma tarefa
• Propósito
– Representar uma operação a ser realizada sobre os elementos
de uma estrutura de objetos como uma classe
– Visitantes permitem definir uma nova operação sem mudar as
classes dos elementos sobre os quais opera
© LES/PUC-Rio
Visitor
• Motivação (Um Problema a ser resolvido)
– Um compilador representa o código como uma árvore sintática;
para cada nó precisa realizar algumas operações
• Representação Inicial: operações distribuídas entre as classes
Pense:
Que problemas tal
arquitetura pode trazer?
© LES/PUC-Rio
Visitor
• Motivação (continuação)
– Problema da arquitetura apresentada:
•
Sistema difícil de compreender,
manter e mudar
•
Acrescentar uma nova operação
exige alteração (e recompilação)
de todas essa classes
– Como resolver?
• E se cada nova operação pudesse ser acrescentada
separadamente?
• E se as classes nós fossem independentes das operações criadas?
© LES/PUC-Rio
Visitor
• Motivação (Solução)
– As possíveis operações são separadas em classes em uma
primeira hierarquia NodeVisitor (Hierarquia de Visitantes)
– Cada classe de operação (Visitante) trata os parâmetros (nós)
possíveis para aquela operação
© LES/PUC-Rio
Visitor
• Motivação (Solução)
– em uma segunda hierarquia define-se os elementos sobre os quais se
aplicam as operações (hierarquia Node) - a Hierarquia de Visitados
– nós passam a ter uma operação para aceitar o Visitor
– Resultado: novas operações podem ser adicionadas separadamente e
as demais classes tornam-se independentes das operações
© LES/PUC-Rio
Visitor
• Aplicabilidade (use o padrão quando:)
– uma estrutura de objetos contém várias classes de objetos
com diferentes interfaces, e se deseja fazer operações nesses
objetos que dependam de suas classes concretas
– queremos separar as operações dos objetos alvo para não
“poluir” o código. Visitor nos permite manter as operações
definindo-as em uma única classe
– O conjunto de objetos-alvo raramente muda (uma vez que
cada novo objeto requer novos métodos em todos os visitors),
mas frequentemente deseja-se definir novas operações
© LES/PUC-Rio
Visitor - Estrutura
© LES/PUC-Rio
Visitor
• Participantes
– Visitor (NodeVisitor)
• Declara uma operação de visita (Visit) para cada classe concreta
(ConcreteElement) na estrutura de objetos
– ConcreteVisitor (TypeCheckingVisitor)
• Implementa cada operação declarada pelo Visitor
– Element (Node)
• Define uma operação Accept que aceita um Visitor
– ConcreteElement (AssignmentNode, VariableRefNode)
• Implementa uma operação Accept que aceita um visitante como argumento
que chama a operação de visita apropriada desse Visitor
– ObjectStructure (Program)
• Pode enumerar seus elementos;
• Pode fornecer uma interface para permitir ao visitante visitar seus elementos
• Pode ser uma composição (um Composite), ou uma coleção, tal como uma
lista ou conjunto
© LES/PUC-Rio
Visitor - Colaborações
•
O cliente deve criar um Visitor e visitar todos os elementos com este Visitor
•
A estrutura de objetos chama Accept(Visitor) para cada elemento e esses
chamam a operação (do Visitor) que corresponde à sua classe
•
o Visitor recebe o elemento sendo visitado para poder acessá-lo, se
desejado
© LES/PUC-Rio
Visitor
• Conseqüências
– Facilidade para incluir novas operações: basta adicionar um novo
Visitor
– Organização e coesão: visitante reúne operações relacionadas e
separa as não relacionadas. Um comportamento relacionado não é
espalhado pelas classes que definem a estrutura de objetos
– Difícil adicionar novos objetos (ConcreteElement): necessidade
de uma nova operação abstrata em Visitor e uma correspondente
implementação em cada classe ConcreteVisitor
– Visitação de hierarquias de classes: um Visitor pode visitar objetos
que não compartilham uma mesma classe mãe. Isso não seria possível,
se um mero iterator fosse usado para varrer a estrutura
– Acumulação de estados: um visitor pode acumular estados durante
as visitas (caso contrário tal estado ficaria em um objeto adicional)
– Quebra de encapsulamento: como a operação está dentro de um
Visitor, e fora de um ConcreteElement, o ConcreteElement poderá ter
que expor mais interfaces do que seria desejável para que o Visitor
possa acessá-lo, Isso pode comprometer a encapsulação.
© LES/PUC-Rio
Visitor
• Exemplo de código (classes envolvidas)
– CarElement
• Wheel (roda): representa um ConcreteElement
• Engine (motor): representa um ConcreteElement
• Body (carroceria): representa um ConcreteElement
– Visitor
• PrintVisitor: representa um ConcreteVisitor
• DoVisitor : representa um ConcreteVisitor
– Car: representa um ObjectStructure
– VisitorDemo : é a main; representa o Client
© LES/PUC-Rio
Visitor – Exemplo de Código
© LES/PUC-Rio
Visitor – Exemplo de Código
Cliente cria objeto
ConcreteVisitor
O objeto é
percorrido por
cada visitante
© LES/PUC-Rio
Fim!!
Download

Slides