Using visual themes in a game In my small application, I need to use a variety of visual themes.

The simplified structure of this class:




Theme
  |
  .__ menu
  |     |
  |     .__ screenBackground
  |     .__ itemsColor
  |     .__ getRandomItemAnimation()
  |
  .__ game
  |     |
  |     .__ screenBackground
  |     .__ gameBoardBackground
  |     .__ getRandomMoveSound()
  |
  .__ getRandomStartScreenImage()



I want to write code like this:

setBackground(theme.game.screenBackground)


instead of

setBackground(theme.game().screenBackground())


But in addition to that, I want to use inheritance. However, Java does not seem to allow to override public fields of the parent class in the descendant classes.

So I've decided to use the following implementation:

Basic classes:



// All constructors (in the next 3 classes) used to set final class-members by descendants

public abstract class Theme {
    public final MenuTheme menu;
    public final GameTheme game;

    public abstract Image getRandomStartScreenImage();

    public Theme(MenuTheme menuTheme, GameTheme gameTheme) {
        this.menuTheme = menuTheme;
        this.gameTheme = gameTheme;
    }
}

public abstract class MenuTheme {
    public final Image screenBackground;
    public final Color itemsColor;

    public abstract Animation getRandomItemAnimation();

    public MenuTheme(Image screenBackground, Color itemsColor) {
        this.screenBackground = screenBackground;
        this.itemsColor = itemsColor;
    }
}

public abstract class GameTheme {
    public final Image screenBackground;
    public final Image gameBoardBackground;

    public abstract Sound getRandomMoveSound();

    public GameTheme(Image screenBackground, Image gameBoardBackground) {
        this.screenBackground = screenBackground;
        this.gameBoardBackground = gameBoardBackground;
    }
}


Using:

public class Menu {
    public void setUp() {
        Theme theme = GameContext.getCurrentTheme();
        setBackground(theme.menu.screenBackground);
        setItemsColor(theme.menu.itemsColor);
    }

    public void onClickItem(Item clickedItem) {
        Theme theme = GameContext.getCurrentTheme();
        clickedItem.startAnimation(theme.menu.getRandomItemAnimation());
        // Action action = getActionByItem(clickedItem);
        // action.start();
    }
}


How to add theme:

public class DarkTheme extends Theme {
    private Image[] startScreenImages = getStartScreenImages();

    public Image getRandomStartScreenImage() {
        return startScreenImages[getRandomIndex()];
    }

    public DarkTheme() {
        super(new DarkMenuTheme(), new DarkGameTheme());
    }
}

public class DarkMenuTheme extends MenuTheme {
    private Animation[] itemAnimations = getItemAnimations();

    public Animation getRandomItemAnimation() {
        return itemAnimations[getRandomIndex()];
    }

    public DarkMenuTheme() {
        super(getDarkMenuScreenBackground(), getDarkMenuItemsColor());
    }
}

public class DarkGameTheme {
    private Sound[] moveSounds = getMoveSounds();

    public Sound getRandomMoveSound() {
        return moveSounds[randomIndex()];
    }

    public DarkGameTheme() {
        super(getDarkGameScreenBackground(), getDarkGameBoardBackground());
    }
}


What do you think about the structure of Theme?  Does it look like a good implementation?

The structure of Theme does not expect to be changed. There will only be the addition of new themes. Given this, what are the drawbacks and benefits of this code?  What improvement or other implementation can you recommend?
I want to write code like this:
  setBackground(theme.game.screenBackground) instead of
  setBackground(theme.game().screenBackground())


Read this : http://c2.com/cgi/wiki?AccessorsAreEvil

The URL is misleading, it is a 'balanced' article, the part I want you to pay particularly attention is this:


  The examples [...] they are really structures (data), not quite
  objects.


Your theme class should really be a structure, and be too simple to have getters.

In response to @bowmore, the Theme should not be responsible for loading resources, the theme should really return resource identifiers.

If it were me, by the way, I would probably go for

game.drawBackground()

where game knows what the theme is, and gets from theme the resource name for the background which a loader class then loads and a UI class then displays.