![]() |
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