![]() |
| Imagem do wikipedia |
Explicação: O coração do padrão é a interface "Visitor", que permite o Visitador (Classe que implementa Visitor), visitar os elementos que implementam ou estendem a interface/classe Element.
Exemplo: Em um Hospital, existem 3 tipos de profissionais: Médico, Secretária e Enfermeira, e para cada tipo de profissional o hospital define um custo por serviço prestado. O exemplo mostra uma forma de obter o custo total que esse hospital vai ter com todos os seus funcionários.
Primeiro criamos uma interface, no qual será implementada pelas classes que desejamos visitar.
public interface Visitable {
public void accept(Visitor visitor);
}
A implementação do nosso modelo, onde as classes Enfermeiro, Medico e Secreteria irão permitir ser visitados.
public class Enfermeiro implements Visitable {
private double totalServico;
public Enfermeiro(double totalServico) {
super();
this.totalServico = totalServico;
}
public double getTotalServico() {
return totalServico;
}
public void setTotalServico(double totalServico) {
this.totalServico = totalServico;
}
public void accept(Visitor visitor) {
visitor.visitar(this);
}
}
public class Secretaria implements Visitable {
private double totalServico;
public Secretaria(double totalServico) {
super();
this.totalServico = totalServico;
}
public double getTotalServico() {
return totalServico;
}
public void setTotalServico(double totalServico) {
this.totalServico = totalServico;
}
public void accept(Visitor visitor) {
visitor.visitar(this);
}
}
public class Medico implements Visitable {
private double totalServico;
public Medico(double totalServico) {
super();
this.totalServico = totalServico;
}
public double getTotalServico() {
return totalServico;
}
public void setTotalServico(double totalServico) {
this.totalServico = totalServico;
}
public void accept(Visitor visitor) {
visitor.visitar(this);
}
}
Para cada tipo de classe concreta, nós precisamos adicionar um método que aceite esta classe.
public interface Visitor {
void visitar(Secretaria secretaria);
void visitar(Enfermeiro enfermeiro);
void visitar(Medico medico);
}
Agora podemos calcular o custo total para cada funcionário, sem adicionar nenhuma lógica as nossas classes modelos:
public class CalculoTotalServico implements Visitor {
private double totalServicosPrestados;
public void visitar(Secretaria secretaria) {
totalServicosPrestados += secretaria.getTotalServico() + 500;
}
public void visitar(Enfermeiro enfermeiro) {
totalServicosPrestados += enfermeiro.getTotalServico() + 700;
}
public void visitar(Medico medico) {
totalServicosPrestados += medico.getTotalServico() + 1000;
}
public double getTotalServicosPrestados() {
return totalServicosPrestados;
}
public void setTotalServicosPrestados(double totalServicosPrestados) {
this.totalServicosPrestados = totalServicosPrestados;
}
}
Iterando sobre a lista de objetos, é possivel obter o custo total gerado por seus funcionários:
public class Main {
public static void main(String[] args) {
CalculoTotalServico calculo = new CalculoTotalServico();
List< Visitable > lista = getLista();
for (Visitable visitable : lista) {
visitable.accept(calculo);
}
System.out.println(calculo.getTotalServicosPrestados());
}
public static List< Visitable > getLista(){
List< Visitable > lista = new ArrayList<>();
lista.add(new Medico(10000));
lista.add(new Medico(15000));
lista.add(new Medico(10000));
lista.add(new Secretaria(15000));
lista.add(new Secretaria(10000));
lista.add(new Enfermeiro(15000));
lista.add(new Enfermeiro(15000));
return lista;
}
}
Visitor é um padrão muito poderoso, que deve ser utilizado com cautela. Obrigado

Nenhum comentário:
Postar um comentário