我的系统存在问题\设计问题。我将从我所在的地方开始:
我正在用Java创建一个游戏引擎,游戏组件通常需要引用游戏的主要单例实例(世界,文件系统等等) - 所以我把我的Game类作为一个静态的全局变量全球类。每当在代码中我需要打开一个文件时,我会写一些类似的东西:
Global.game.getFilesystem()。中openFile(...)
没有实际的方法来不断传递这个Game对象。我一直在避免像瘟疫这样的单身设计模式,而宁愿在这个模式周围工作......
无论如何,现在我有了我的GameCore库,就是这样。我正在用它实现一个游戏。显然,在这个过程中我想扩展游戏。问题是,现在我的类需要一种方便的方式来访问相同类型的资源 - 这很好 - 除了它不能使用Global.game,因为Global.game只能被引用为抽象类Game(即使它包含MyRpgGame的一个实例,我可能需要MyRpgGame类型的实例。当然,我可以进行类型转换,但它在整个代码中都是混乱且不变的。所以我提出的唯一解决方案(尽管我真的不喜欢它......)是这样的:
我通过Game.game或RpgGame.game等参考游戏......
public abstract class Game
{
...
public static Game game = null;
public Game()
{
if(game != null)
throw new InitializationException("Cannot instantiate multiple instances of game.");
game = this;
...
}
然后在我的RpgGame中,我在游戏中隐藏了静态场比赛:
public class RpgGame extends Game
{
public static RpgGame game = null;
public RpgGame()
{
if(game != null)
throw new InitializationException("Cannot instantiate multiple instances of game.");
game = this;
}
答案 0 :(得分:2)
您需要的是依赖注入支持。它将消除你所有的问题,因为依赖注入可以基于接口,而不是特定的类,你不必传递它们 - 它们只是自动注入。
结帐Google Guice或Spring Framework。 Google Guice更轻量级,但Spring Framework提供了许多内置功能,并且拥有庞大的生态系统。
答案 1 :(得分:0)
这是我在游戏中正在用javascript编写的内容。这在Java中可能是非惯用的。请记住,我正在尝试以函数式编程风格编写游戏。以下是它的工作原理:我有一个名为gameState
的全局变量。它只能用这样的方法分配:
applyTick()
global.gameState = tick(global.gameState)
renderGameState(gameState)
游戏循环一遍又一遍地调用applyTick()
。在除此之外的每个方法中,您处理本地 gameState
实例,并且我的大多数方法都有这样的签名:
gameState = methodName(gameState)
这样就可以很容易地改变我的操作顺序。
如果我需要一些像score,
这样的新数据,我只需将其添加到GameState
对象中,只有关注score
的方法必须更改。请记住,我没有在GameState
对象中添加任何逻辑。这纯粹是数据。
我不知道这是一种做事还是坏事的好方法。我自己对此持怀疑态度。我一直在想,这将成为一个维护噩梦,我很难推理我的计划。但到目前为止,恰恰相反。这个“模式”已经很好地工作了3个多月。