在我的小应用程序中,我需要使用各种视觉主题。
这类的简化结构:
主题曲:.__菜单,.__,screenBackground,.__,itemsColor,getRandomItemAnimation,getRandomItemAnimation(),.__,getRandomItemAnimation,.__,getRandomItemAnimation,.__,.__,getRandomItemAnimation,.__,getRandomItemAnimation,.__,.__,getRandomItemAnimation,.__,getRandomItemAnimation,.__,.__,getRandomItemAnimation,.__,getRandomItemAnimation,.__,.__,getRandomItemAnimation,.__,.__,getRandomItemAnimation
我想写这样的代码:
setBackground(theme.game.screenBackground)而不是
setBackground(theme.game().screenBackground())但除此之外,我还想使用继承。但是,Java似乎不允许覆盖子类中父类的公共字段。
因此,我决定使用以下实现:
// 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;
}
}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();
}
}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());
}
}你对Theme的结构有什么看法?它看起来像一个很好的实现吗?
Theme的结构不会改变。只会增加新的主题。考虑到这一点,该代码的缺点和好处是什么?您可以推荐哪些改进或其他实现?
发布于 2013-09-10 20:30:07
我想编写这样的代码: setBackground(theme.game.screenBackground)而不是setBackground
读这个:http://c2.com/cgi/wiki?AccessorsAreEvil
网址有误导性,它是一篇“平衡”的文章,我想让你特别注意的部分是:
示例... --它们实际上是结构(数据),而不是完全的对象。
您的主题类应该是一个结构,并且太简单,不应该有getter。
响应@bowmore,主题不应该负责加载资源,主题应该真正返回资源标识符。
顺便说一句,如果是我,我可能会
game.drawBackground()
其中,游戏知道主题是什么,并从主题获取资源名称的背景,然后加载类加载,然后显示UI类。
发布于 2013-09-10 19:44:56
我想编写这样的代码:
setBackground(theme.game.screenBackground)而不是setBackground(theme.game().screenBackground())。
为什么你要牺牲封装(面向对象设计的第一原则)来减少输入括号的小方便呢?
坦率地说,我看不到任何真正的好处,但我可以看到几个缺点:
我相信这些观点在Java以外的其他语言中也是有效的。
发布于 2013-09-11 09:50:30
一言为定的建议
protected (公众毫无意义)的构造函数。https://codereview.stackexchange.com/questions/31065
复制相似问题