Clean OOP way of mapping an object to its presenter

I am creating a board game (such as chess) in Java, where each piece is its own type (like Pawn, Rook etc.). For the GUI part of the application I need an image for each of these pieces. Since doing thinks like rook.image(); violates separation of UI and business logic, I will create a different presenter for each piece and then map the piece types to their corresponding presenters like private HashMap<Class<Piece>, PiecePresenter> presenters = ... public Image getImage(Piece piece) { return presenters.get(piece.getClass()).image(); } So far so good. However, I sense a prudent OOP guru would frown upon calling a getClass() method and would suggest using a visitor for example like this: 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; } } I like this solution (thank you, guru), but it has one significant drawback. Every time a new piece type is added to the application the PieceVisitor needs to be updated with a new method. I would like to use my system as a board game framework where new pieces could be added through a simple process where the user of the framework would only provide implementation of both the piece and its presenter, and simply plug it into the framework. My question: is there a clean OOP solution without instanceof, getClass() etc. which would allow for this kind of extensibility?

Jan 26, 2025 - 19:14
 0
Clean OOP way of mapping an object to its presenter

I am creating a board game (such as chess) in Java, where each piece is its own type (like Pawn, Rook etc.). For the GUI part of the application I need an image for each of these pieces. Since doing thinks like

rook.image();

violates separation of UI and business logic, I will create a different presenter for each piece and then map the piece types to their corresponding presenters like

private HashMap<Class<Piece>, PiecePresenter> presenters = ...

public Image getImage(Piece piece) {
  return presenters.get(piece.getClass()).image();
}

So far so good. However, I sense a prudent OOP guru would frown upon calling a getClass() method and would suggest using a visitor for example like this:

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;
  } 
}

I like this solution (thank you, guru), but it has one significant drawback. Every time a new piece type is added to the application the PieceVisitor needs to be updated with a new method. I would like to use my system as a board game framework where new pieces could be added through a simple process where the user of the framework would only provide implementation of both the piece and its presenter, and simply plug it into the framework. My question: is there a clean OOP solution without instanceof, getClass() etc. which would allow for this kind of extensibility?