Visitor (padrão de desenho): Difference between revisions

From Wiki**3

Root (talk | contribs)
Root (talk | contribs)
No edit summary
 
(6 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{NAVPO}}
{{TOCright}}
{{TOCright}}
O padrão ''visitor'' permite separar uma estrutura de objectos de algoritmos que a ela possam ser associados em tempo de execução. A adição do comportamento processa-se sem alteração objecto "visitado".
O padrão ''visitor'' permite separar uma estrutura de objectos de algoritmos que a ela possam ser associados em tempo de execução. A adição do comportamento processa-se sem alteração do código da classe do objecto "visitado".


==Estrutura==
==Estrutura==
Line 18: Line 19:
==Exemplo==
==Exemplo==


=== Visitantes ===
* [[Visitor (padrão de desenho)/Expressões Aritméticas Simples|Expressões Aritméticas Simples]]
* [[Visitor (padrão de desenho)/Produtos Hortícolas|Produtos Hortícolas]]


Os visitantes implementam a interface <code>Visitante</code>:
== Exercícios ==


<java5>
* [[Visitor (padrão de desenho)/Exercício 1: Cálculo de Impostos|Cálculo de Impostos]]
  interface Visitante {
    void visita(Alface g);
    void visita(Batata r);
    void visita(Cebola c);
  }
</java5>


Note-se que esta interface prevê que os métodos sejam seleccionados por um mecanismo da linguagem (''overloading'') em lugar de se definir um conjunto de métodos com nomes explicitamente distintos.
[[category:Ensino]]
 
[[category:PO]]
A primeira implementação adiciona a capacidade de descrição a cada produto hortícola.
 
<java5>
  class Descrição implements Visitante {
    private String s; 
    public String toString()    { return s; }
    public void visita(Alface a) { s = "Alface"; }
    public void visita(Batata b) { s = "Batata"; }
    public void visita(Cebola c) { s = "Cebola"; }
  }
</java5>
 
A primeira implementação simula a capacidade de interacção entre um animal (visitante) e um produto hortícola.
 
<java5>
  class Animal implements Visitante { 
    public void visita(Alface a) { System.out.println("Animal & Alface"); }
    public void visita(Batata b) { System.out.println("Animal & Batata"); }
    public void visita(Cebola c) { System.out.println("Animal & Cebola"); }
  }
</java5>
 
=== Produtos ===
 
A hierarquia de produtos hortícolas implementa uma interface comum que impõe a aceitação de visitantes.
 
<java5>
  interface Hortícola {
    void aceita(Visitante v);
  }
</java5>
 
Note-se que as várias implementações são meras esquematizações: a semelhança entre as implmentações do método <code>aceita</code> resulta da simplicidade do exemplo (o método pode ser, como seria de esperar, arbitrariamente complexo).
 
<java5>
  class Alface implements Hortícola { 
    public void aceita(Visitante v) { v.visita(this); }
  }
</java5>
 
<java5>
  class Batata implements Hortícola { 
    public void aceita(Visitante v) { v.visita(this); }
  }
</java5>
 
<java5>
  class Cebola implements Hortícola { 
    public void aceita(Visitante v) { v.visita(this); }
  }
</java5>
 
=== Teste ===
 
O teste utiliza uma ''factory'' simples para gerar produtos hortícolas aleatórios.
 
<java5>
  class Horta {
    public static Hortícola produto() {
      switch ((int)(Math.random() * 3)) {
        default:
        case 0: return new Alface();
        case 1: return new Batata();
        case 2: return new Cebola();
      }
    }
  }
</java5>
 
Note-se a acção dos visitantes no seguinte teste.
 
<java5>
  public class Teste extends TestCase {
    List<Hortícola> _produtos = new ArrayList<Hortícola>();
    public Teste() {
      for (int i = 0; i < 10; i++)
        _produtos.add(Horta.produto());
    }
    public void test() {
      // Apresenta as descrições de cada produto
      Descrição dsc = new Descrição();
      for (Hortícola h : _produtos) {
        h.aceita(dsc);
        System.out.println(dsc);
      }
      // Animal visita horta
      Animal a = new Animal();
      for (Hortícola h : _produtos)
        h.aceita(a);
    }
    public static void main(String args[]) {
      new Teste().test();
    }
  }
</java5>
 
[[category:OOP]]
[[category:Teaching]]

Latest revision as of 18:52, 20 December 2015

Programação com Objectos
Introduction
Creation and Destruction
Inheritance & Composition
Abstraction & Polymorphism
Code Organization
Java Topics
Inner Classes
Enumerations
Data Structures
Exceptions
Input/Output
RTTI
Other Topics
JUnit Tests
UML Topics
Design Patterns
"Simple" Factory
Composite & Visitor
Command
Strategy & State
Template Method
Observer
Abstract Factory
Decorator & Adapter
Façade (aka Facade)

O padrão visitor permite separar uma estrutura de objectos de algoritmos que a ela possam ser associados em tempo de execução. A adição do comportamento processa-se sem alteração do código da classe do objecto "visitado".

Estrutura

Diagrama de classes

O padrão visitor tem a seguinte estrutura de classes:

Diagrama de sequência

As colaborações entre os intervenientes são as que figuram no seguinte diagrama de sequência:

Exemplo

Exercícios