Sirve para quitar los operadores instanceof
de un método para respetar el principio open/closed
convirtiendo cada pedazo de código en un método dentro de la misma clase que contenía el método con los instanceof
.
Los archivos de este snippet demuestran un ejemplo correcto de la técnica de doble despacho. También se pudo haber definido cómo visita el recepcionista a un hombre y a una mujer en las clases Hombre
y Mujer
, respetando el principio open/closed
pero delegando la implementación de cómo visita el recepcionista al Hombre
y a la Mujer
en dichas clases, dando la responsabilidad del Recepcionista
al Hombre
y a la Mujer
.
Qué pasa si ahora la persona tuviese que aceptar no solo a un Recepcionsta
sino también a un Camarero
, a un Gerente
, y a un Cajero
. Si agregaramos múltiples métodos dentro de Hombre
/Mujer
para aceptar a todos los roles, crearíamos un alto acoplamiento de Hombre
/Mujer
hacia ellos. La solución es crear una interfaz llamada VisitadorPersona
que sería la interfaz con la que trabajaría el Hombre
/Mujer
y Recepcionsta
,Camarero
,Gerente
,Cajero
implementarían a VisitadorPersona
.
import java.text.NumberFormat;
public class Recepcionista {
public void recibir(Persona persona) {
// El objetivo es eliminar el instanceof y crear métodos DENTRO DE ESTA MISMA CLASE
// De acuerdo al tipo de objeto son las operaciones que se deben ejecutar
// if (persona instanceof Hombre) {
// System.out.println("hombre bienvenido sea usted caballero");
// recibirPropina(5);
// } else if (persona instanceof Mujer) {
// System.out.println("mujer bienvenida guapa, es usted bellisima");
// mujer.sonrojar();
// }
persona.aceptar(this);
}
public void agradecerVisita() {
System.out.println("gracias por venir a este su restaurante");
}
public void recibirPropina(double cantidad) {
NumberFormat format = NumberFormat.getCurrencyInstance();
String cant = format.format(cantidad);
System.out.println("recepcionista: he recibido " + cant);
}
public void visitar(Hombre hombre) {
System.out.println("hombre bienvenido sea usted caballero");
recibirPropina(5);
}
public void visitar(Mujer mujer) {
System.out.println("mujer bienvenida guapa, es usted bellisima");
mujer.sonrojar();
}
}
public abstract class Persona {
public void saludar() {
System.out.println("buenas tardes");
}
public void despedirse() {
System.out.println("hasta luego!!!!");
}
public abstract void aceptar(Recepcionista recepcionista);
}
public class Mujer extends Persona {
public void sonrojar() {
System.out.println("me sonroja todita!");
}
@Override
public void aceptar(Recepcionista recepcionista) {
recepcionista.visitar(this);
}
}
public class Hombre extends Persona {
@Override
public void aceptar(Recepcionista recepcionista) {
recepcionista.visitar(this);
}
}
import java.util.Random;
public class Restaurante {
private Recepcionista recepcionista;
public static void main(String[] args) {
Restaurante restaurante = new Restaurante();
restaurante.recepcionista = new Recepcionista();
Random random = new Random(System.currentTimeMillis());
for (int i = 0; i < 5; i++) {
Persona persona;
if (random.nextInt(2) == 0) {
persona = new Hombre();
} else {
persona = new Mujer();
}
restaurante.simularEscenario(persona);
}
}
private void simularEscenario(Persona persona) {
persona.saludar();
recepcionista.recibir(persona);
persona.despedirse();
recepcionista.agradecerVisita();
System.out.println("-------------------");
System.out.println("pasa un tiempo...");
System.out.println("-------------------");
}
}