Estoy creando un juego de mesa (como el ajedrez) en Java, donde cada pieza es de su propio tipo (como Pawn
, Rook
, etc.). 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 mapearé 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 ahora todo bien. Sin embargo, siento que un gurú de OOP prudente frunciría el ceño al llamar al método getClass()
y sugeriría usar un visitante como este:
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 donde 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 lo conectaría al marco. Mi pregunta: ¿hay una solución de POO limpia sin instanceof
, getClass()
etc. que permitiría este tipo de extensibilidad?