Estoy creando un juego de mesa (como el ajedrez) en Java, donde cada pieza es de su propio tipo (como Pawn, Rooketc.). Para la parte GUI de la aplicación, necesito una imagen para cada una de estas piezas. Ya que hacer piensa como
rook.image();
viola la separación de la interfaz de usuario y la lógica empresarial, crearé un presentador diferente para cada pieza y luego asignaré los tipos de piezas a sus presentadores correspondientes, como
private HashMap<Class<Piece>, PiecePresenter> presenters = ...
public Image getImage(Piece piece) {
return presenters.get(piece.getClass()).image();
}
Hasta aquí todo bien. Sin embargo, siento que un gurú prudente de OOP frunciría el ceño al llamar a un getClass()método y sugeriría usar un visitante, por ejemplo, así:
class Rook extends Piece {
@Override
public <T> T accept(PieceVisitor<T> visitor) {
return visitor.visitRook(this);
}
}
class ImageVisitor implements PieceVisitor<Image> {
@Override
public Image visitRook(Rook rook) {
return rookImage;
}
}
Me gusta esta solución (gracias, gurú), pero tiene un inconveniente importante. Cada vez que se agrega un nuevo tipo de pieza a la aplicación, PieceVisitor debe actualizarse con un nuevo método. Me gustaría usar mi sistema como un marco de juego de mesa en el que se podrían agregar nuevas piezas a través de un proceso simple en el que el usuario del marco solo proporcionaría la implementación tanto de la pieza como de su presentador, y simplemente se conectaría al marco. Mi pregunta: ¿existe una solución de programación orientada a objetos limpios y sin instanceof, getClass()etc., que permita este tipo de extensibilidad?
