Visitor (padrão de desenho): Difference between revisions
From Wiki**3
No edit summary |
|||
| Line 70: | Line 70: | ||
<FONT COLOR="#0000ff">public</FONT> <FONT COLOR="#0000ff">void</FONT> aceita(Visitante v) { v.visita(<FONT COLOR="#0000ff">this</FONT>); } | <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. | |||
<FONT COLOR="#0000ff">public</FONT> <FONT COLOR="#0000ff">class</FONT> Teste <FONT COLOR="#0000ff">extends</FONT> TestCase { | |||
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:PO 2005/2006]] | [[category:PO 2005/2006]] | ||
Revision as of 16:36, 19 November 2005
Material correspondente à aula 29.
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".
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
Visitantes
Os visitantes implementam a interface Visitante:
interface Visitante {
void visita(Alface g);
void visita(Batata r);
void 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.
class Descrição implements Visitante {
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"; }
}
A primeira implementação simula a capacidade de interacção entre um animal (visitante) e um produto hortÃcola.
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"); }
}
Produtos
A hierarquia de produtos hortÃcolas implementa uma interface comum que impõe a aceitação de visitantes.
interface Hortícola {
void 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 aceita resulta da simplicidade do exemplo (o método pode ser, como seria de esperar, arbitrariamente complexo).
class Alface implements Hortícola {
public void aceita(Visitante v) { v.visita(this); }
}
class Batata implements Hortícola {
public void aceita(Visitante v) { v.visita(this); }
}
class Cebola implements Hortícola {
public void aceita(Visitante v) { v.visita(this); }
}
Teste
O teste utiliza uma factory simples para gerar produtos hortÃcolas aleatórios.
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();
}
}
}
Note-se a acção dos visitantes no seguinte teste.
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();
}
}