m (Visitor (padrão de desenho) moved to Visitor (padrão de desenho)) |
|||
Line 1: | Line 1: | ||
− | + | {{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 objecto "visitado". | ||
Line 11: | Line 10: | ||
[[Image:visitor-dpcd.png|600px]] | [[Image:visitor-dpcd.png|600px]] | ||
− | ===Diagrama de | + | ===Diagrama de sequência=== |
− | As colaborações entre os intervenientes são as que figuram no seguinte diagrama de | + | 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 23: | Line 22: | ||
Os visitantes implementam a interface <code>Visitante</code>: | Os visitantes implementam a interface <code>Visitante</code>: | ||
− | + | <java5> | |
− | + | interface Visitante { | |
− | + | void visita(Alface g); | |
− | + | void visita(Batata r); | |
+ | void visita(Cebola c); | ||
} | } | ||
+ | </java5> | ||
− | Note-se que esta interface | + | 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. | A primeira implementação adiciona a capacidade de descrição a cada produto hortÃcola. | ||
− | + | <java5> | |
− | String s; | + | 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 | + | 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 === | === Produtos === | ||
− | A hierarquia de 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). | 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). |
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 tem a seguinte estrutura de classes:
As colaborações entre os intervenientes são as que figuram no seguinte diagrama de sequência:
Os visitantes implementam a interface Visitante
:
<java5>
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.
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>
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 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); } }
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(); } }