Difference between revisions of "Visitor (padrão de desenho)"

From Wiki**3

 
(9 intermediate revisions by the same user not shown)
Line 1: Line 1:
Material correspondente à aula 29.
+
{{NAVPO}}
 
+
{{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 11: Line 11:
 
[[Image:visitor-dpcd.png|600px]]
 
[[Image:visitor-dpcd.png|600px]]
  
===Diagrama de sequência===
+
===Diagrama de sequência===
  
As colaborações entre os intervenientes são as que figuram no seguinte diagrama de sequência:
+
As colaborações entre os intervenientes são as que figuram no seguinte diagrama de sequência:
  
 
[[Image:visitor-dpsd.png|600px]]
 
[[Image:visitor-dpsd.png|600px]]
Line 19: 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>:
 
 
 
  <FONT COLOR="#0000ff">interface</FONT> Visitante {
 
    <FONT COLOR="#0000ff">void</FONT> visita(Alface g);
 
    <FONT COLOR="#0000ff">void</FONT> visita(Batata r);
 
    <FONT COLOR="#0000ff">void</FONT> visita(Cebola c);
 
  }
 
 
 
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.
 
 
 
A primeira implementação adiciona a capacidade de descrição a cada produto hortícola.
 
 
 
  <FONT COLOR="#0000ff">class</FONT> Descri&ccedil;&atilde;o <FONT COLOR="#0000ff">implements</FONT> Visitante {
 
    String s; 
 
    <FONT COLOR="#0000ff">public</FONT> String toString() { <FONT COLOR="#0000ff">return</FONT> s; }
 
    <FONT COLOR="#0000ff">public</FONT> <FONT COLOR="#0000ff">void</FONT> visita(Alface a) { s = <FONT COLOR="#004488">&quot;Alface&quot;</FONT>; }
 
    <FONT COLOR="#0000ff">public</FONT> <FONT COLOR="#0000ff">void</FONT> visita(Batata b) { s = <FONT COLOR="#004488">&quot;Batata&quot;</FONT>; }
 
    <FONT COLOR="#0000ff">public</FONT> <FONT COLOR="#0000ff">void</FONT> visita(Cebola c) { s = <FONT COLOR="#004488">&quot;Cebola&quot;</FONT>; }
 
  }
 
 
 
A primeira implementação simula a capacidade de interacção entre um animal (visitante) e um produto hortícola.
 
 
 
  <FONT COLOR="#0000ff">class</FONT> Animal <FONT COLOR="#0000ff">implements</FONT> Visitante { 
 
    <FONT COLOR="#0000ff">public</FONT> <FONT COLOR="#0000ff">void</FONT> visita(Alface a) { System.out.println(<FONT COLOR="#004488">&quot;Animal &amp; Alface&quot;</FONT>); }
 
    <FONT COLOR="#0000ff">public</FONT> <FONT COLOR="#0000ff">void</FONT> visita(Batata b) { System.out.println(<FONT COLOR="#004488">&quot;Animal &amp; Batata&quot;</FONT>); }
 
    <FONT COLOR="#0000ff">public</FONT> <FONT COLOR="#0000ff">void</FONT> visita(Cebola c) { System.out.println(<FONT COLOR="#004488">&quot;Animal &amp; Cebola&quot;</FONT>); }
 
  }
 
 
 
=== Produtos ===
 
 
 
A hierarquia de produtos hortícolas implementa uma interface comum que impõe a aceitação de visitantes.
 
 
 
  <FONT COLOR="#0000ff">interface</FONT> Hort&iacute;cola {
 
    <FONT COLOR="#0000ff">void</FONT> aceita(Visitante v);
 
  }
 
 
 
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).
 
 
 
  <FONT COLOR="#0000ff">class</FONT> Alface <FONT COLOR="#0000ff">implements</FONT> Hort&iacute;cola { 
 
    <FONT COLOR="#0000ff">public</FONT> <FONT COLOR="#0000ff">void</FONT> aceita(Visitante v) { v.visita(<FONT COLOR="#0000ff">this</FONT>); }
 
  }
 
 
 
  <FONT COLOR="#0000ff">class</FONT> Batata <FONT COLOR="#0000ff">implements</FONT> Hort&iacute;cola { 
 
    <FONT COLOR="#0000ff">public</FONT> <FONT COLOR="#0000ff">void</FONT> aceita(Visitante v) { v.visita(<FONT COLOR="#0000ff">this</FONT>); }
 
  }
 
 
 
  <FONT COLOR="#0000ff">class</FONT> Cebola <FONT COLOR="#0000ff">implements</FONT> Hort&iacute;cola { 
 
    <FONT COLOR="#0000ff">public</FONT> <FONT COLOR="#0000ff">void</FONT> aceita(Visitante v) { v.visita(<FONT COLOR="#0000ff">this</FONT>); }
 
  }
 
 
 
=== Teste ===
 
 
 
O teste utiliza uma ''factory'' simples para gerar produtos hortícolas aleatórios.
 
 
 
  <FONT COLOR="#0000ff">class</FONT> Horta {
 
    <FONT COLOR="#0000ff">public</FONT> <FONT COLOR="#0000ff">static</FONT> Hort&iacute;cola produto() {
 
      <FONT COLOR="#0000ff">switch</FONT>((<FONT COLOR="#0000ff">int</FONT>)(Math.random() * 3)) {
 
        <FONT COLOR="#0000ff">default</FONT>:
 
        <FONT COLOR="#0000ff">case</FONT> 0: <FONT COLOR="#0000ff">return</FONT> <FONT COLOR="#0000ff">new</FONT> Alface();
 
        <FONT COLOR="#0000ff">case</FONT> 1: <FONT COLOR="#0000ff">return</FONT> <FONT COLOR="#0000ff">new</FONT> Batata();
 
        <FONT COLOR="#0000ff">case</FONT> 2: <FONT COLOR="#0000ff">return</FONT> <FONT COLOR="#0000ff">new</FONT> Cebola();
 
      }
 
    }
 
  }
 
  
Note-se a acção dos visitantes no seguinte teste.
+
== Exercícios ==
  
  <FONT COLOR="#0000ff">public</FONT> <FONT COLOR="#0000ff">class</FONT> Teste <FONT COLOR="#0000ff">extends</FONT> TestCase {
+
* [[Visitor (padrão de desenho)/Exercício 1: Cálculo de Impostos|Cálculo de Impostos]]
    List&lt;Hort&iacute;cola&gt; _produtos = <FONT COLOR="#0000ff">new</FONT> ArrayList&lt;Hort&iacute;cola&gt;();
 
 
    <FONT COLOR="#0000ff">public</FONT> Teste() {
 
      <FONT COLOR="#0000ff">for</FONT>(<FONT COLOR="#0000ff">int</FONT> i = 0; i &lt; 10; i++)
 
        _produtos.add(Horta.produto());
 
    }
 
 
    <FONT COLOR="#0000ff">public</FONT> <FONT COLOR="#0000ff">void</FONT> test() {
 
      <FONT COLOR="#009900">// Apresenta as descri&ccedil;&otilde;es de cada produto</FONT>
 
      Descri&ccedil;&atilde;o dsc = <FONT COLOR="#0000ff">new</FONT> Descri&ccedil;&atilde;o();
 
      for (Hort&iacute;cola h : _produtos) {
 
        h.aceita(dsc);
 
        System.out.println(dsc);
 
      }
 
 
      <FONT COLOR="#009900">// Animal visita horta</FONT>
 
      Animal a = <FONT COLOR="#0000ff">new</FONT> Animal();
 
      for (Hort&iacute;cola h : _produtos)
 
        h.aceita(a);
 
    }
 
 
    <FONT COLOR="#0000ff">public</FONT> <FONT COLOR="#0000ff">static</FONT> <FONT COLOR="#0000ff">void</FONT> main(String args[]) {
 
      <FONT COLOR="#0000ff">new</FONT> Teste().test();
 
    }
 
  }
 
  
[[category:OOP]]
+
[[category:Ensino]]
[[category:Teaching]]
+
[[category:PO]]

Latest revision as of 19: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:

Visitor-dpcd.png

Diagrama de sequência

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

Visitor-dpsd.png

Exemplo

Exercícios