|
|
(10 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çã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">"Alface"</FONT>; }
| |
− | <FONT COLOR="#0000ff">public</FONT> <FONT COLOR="#0000ff">void</FONT> visita(Batata b) { s = <FONT COLOR="#004488">"Batata"</FONT>; }
| |
− | <FONT COLOR="#0000ff">public</FONT> <FONT COLOR="#0000ff">void</FONT> visita(Cebola c) { s = <FONT COLOR="#004488">"Cebola"</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">"Animal & Alface"</FONT>); }
| |
− | <FONT COLOR="#0000ff">public</FONT> <FONT COLOR="#0000ff">void</FONT> visita(Batata b) { System.out.println(<FONT COLOR="#004488">"Animal & Batata"</FONT>); }
| |
− | <FONT COLOR="#0000ff">public</FONT> <FONT COLOR="#0000ff">void</FONT> visita(Cebola c) { System.out.println(<FONT COLOR="#004488">"Animal & Cebola"</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í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í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í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í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í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<Hortícola> _produtos = <FONT COLOR="#0000ff">new</FONT> ArrayList<Hortícola>();
| |
− |
| |
− | <FONT COLOR="#0000ff">public</FONT> Teste() {
| |
− | <FONT COLOR="#0000ff">for</FONT>(<FONT COLOR="#0000ff">int</FONT> i = 0; i < 10; i++)
| |
− | _produtos.add(Horta.produto());
| |
− | }
| |
− |
| |
− | <FONT COLOR="#0000ff">public</FONT> <FONT COLOR="#0000ff">void</FONT> test() {
| |
− | <FONT COLOR="#009900">// Apresenta as descrições de cada produto</FONT>
| |
− | Descrição dsc = <FONT COLOR="#0000ff">new</FONT> Descrição();
| |
− | for (Hortí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í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]] |
As colaborações entre os intervenientes são as que figuram no seguinte diagrama de sequência: