Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
面向对象Java有一些问题,对吗?_Java_Oop - Fatal编程技术网

面向对象Java有一些问题,对吗?

面向对象Java有一些问题,对吗?,java,oop,Java,Oop,我正在构建一个游戏,我决定用一个GameState抽象类来组织它,这样我就可以定义菜单、级别和其他东西了 我有一个名为GameStateManager的类,它保存所有状态,并在需要时更改它们。 仅仅为了访问GameStateManager的状态更改方法而向GameStateMonstructor传递GameStateManager的实例是否正确 如果没有,还有别的办法吗 仅仅为了访问GameStateManager的状态更改方法而向GameStateMonstructor传递GameStateM

我正在构建一个游戏,我决定用一个GameState抽象类来组织它,这样我就可以定义菜单、级别和其他东西了

我有一个名为GameStateManager的类,它保存所有状态,并在需要时更改它们。 仅仅为了访问GameStateManager的状态更改方法而向GameStateMonstructor传递GameStateManager的实例是否正确

如果没有,还有别的办法吗

仅仅为了访问GameStateManager的状态更改方法而向GameStateMonstructor传递GameStateManager的实例是否正确

没有

您应该只有一个管理器实例和一个引用。这意味着您应该使用基于实例的系统。例如:

GameStateManager instance = GameStateManager.getInstance();
这样您就可以静态地访问它

这可以通过以下方式实现:

// in GameStateManager.java

private static GameStateManager instance;

protected static GameStateManager getInstance(){
    if(instance == null){
        instance = new GameStateManager(); //private constructor
    }
    return instance;
} 
我假设受保护将在这里工作,因为所有游戏状态实例都与GameStateManager位于同一个包中。

如果游戏状态可以有一个游戏状态集合,则将GameStateManager的实例传递给GameStateManager是有意义的,因为您需要GameStateManager来管理该游戏状态的游戏状态

但是,如果不是这样,我认为将GameStateManager传递给GameState构造函数是没有意义的。GameStateManager的全部目的是更改状态,因此,除非出现上述情况,否则不应使用GameStateManager更改其他状态


如果您试图找出如何通知GameStateManager当前游戏状态需要更改,您可以在GameStateManager中使用一个静态方法,您可以从GameState调用该方法来更改当前游戏状态。如果您不想将其公开,这是有道理的,只要您的类在同一个包中,就可以将其设置为静态保护。那应该适合你的目的

在OO中思考,您需要问问自己GameStateManager上的GameState是否具有硬依赖组合,即没有GameStateManager它无法执行,然后您可以使用构造函数传递GameStateManager


如果GameStateManager上的GameStateManager具有软依赖聚合,即它可以在没有GameStateManager的情况下执行,然后,您可以使用getter/setter传递GameStateManager。

我认为最干净的解决方案是使用:GameStateManager知道所有的游戏状态,他是观察者,必须实现notify方法,他可以在其中处理游戏状态更改的逻辑

创建新游戏状态后,GameStateManager必须将自己注册为观察者,如下所示:newGameState.registerObserverthis


当主题的游戏状态发生更改时,它会为所有侦听器调用notify,例如,仅调用单个GameStateManager。这样,游戏状态根本不需要知道GameStateManager,只需要知道如果它发生了变化,一些观察者会收到什么通知。

GameStateManager和GameStateManager有什么区别?我没有注意到这一点。这对我来说并不是不合理的,可能一些用法示例会让这个想法更清晰。而且只是提醒您,这可能是堆栈溢出的主题,如果您将其设置为足够通用的问题GameStateManager保存所有游戏状态,并设置当前正在运行的状态,则可能是程序员的主题。@Thomas可能相当于物理引擎和物理对象之间的关系。一个管理,一个是,在一些实现中,它们都有相互引用,所以我可以仅仅因为它们相关就传递一个实例吗?我已经考虑过sigleton模式,但假设我想要两个游戏在同一台计算机和同一个JVM中运行,我不希望他们每次都有相同的状态。@PatriqDesigns这不会发生。GameStateManager没有任何需要单例的地方,除非你绝对确定它应该是单例,否则将其设置为单例是不好的。尽管这种情况非常不可能发生,考虑到我找不到合适的情况,你可以在线程组的基础上管理它们,因为每个线程组都有自己的GameStateManager。你如何知道GameStateManager是否不能有多个实例?在这个问题上甚至没有足够的信息来了解这一点。像这样的大多数单例模式只是隐藏全局变量的粗略方式。是的!我知道,那么我该如何改变状态,想象一下,如果在菜单中我点击了开始选项,那么对于PlayingState,我该如何改变状态?@PatriqDesigns我在底部添加了一段。希望这有帮助,祝你好运!在我看来,你可能真正想要的是GameStateManager成为游戏状态的工厂,但这取决于是否有太多不同的类实现GameState