我正在用纯Java制作游戏(很大程度上是一种学习经历,因为我对编程还很陌生),我发现我不断传递相同的引用,即“manager”类型高级单例对象:World、PlayerManager、EnemyManager、TargetManager、ItemManager 等
目前我只静态引用我的 Final Constants/Utility 方法类,其中包含类似于 java.lang.Math 的内容。
我的想法是,对这些对象进行静态引用将大大减少传递量,并且 this.boop = boop'ing 我必须做,但有些感觉不好的做法关于它,我不确定为什么。
我不必担心线程安全
我想要静态引用的所有对象都是在游戏开始时创建的单例
这样做有什么缺点?
编辑:
为了避免使用 Static,我可以创建一个 ReferenceManager 对象并传递它,但这似乎不必要地迟钝。
最佳答案
优点显然是性能:如果您可以通过更少的步骤访问所需的实例,那么您就可以更快地开始使用它。此外,如果您在应用程序启动时初始化这些“单例”,则当其他模块尝试访问时不会出现任何命中,因此您的单例甚至不需要 if null then instantiate
getInstance()
中的典型逻辑实现。
一个缺点是高耦合。现在,您的模块都专门了解此实例以及如何访问它。这使得维护以及单元测试、模拟等变得更加困难,因为您的模块只知道那个实例。另外,您无法对 TargetManager
进行第二次实现在启动时或动态地以一种或另一种方式更有效地交换它们或选择一个用于不同的目的(OO实例替换)。
另一个缺点是单例:现在你不能拥有第二个 World
。它可能永远不会出现,但如果您制作服务器/客户端应用程序,服务器可能会跟踪多个 World
实例,这变得很难重构。您可以使用类似 world1.get()
的内容和world2.get()
并且只有两个单例,现在您的模块需要知道要获取哪个。这会使事情变得非常复杂,因为所有东西都需要知道标准以及访问方式,而如果您传递引用(本质上只是注入(inject)),那么每个模块对其环境的了解就会更少,这又是一个耦合加号。
在某些情况下,例如 OSGI,会使用类加载器,因此在某些情况下单例并不是真正的单例。
我确信还有一些其他有用的博客文章和此类在线博客文章反对在某种情况下使用单例。
除此之外,游戏编程就是要走捷径,所以如果您知道不必担心任何这些情况,那么不通过代码层传递引用就是性能上的胜利,并且直接访问而不是某种注册表查找是另一种方法。在系统编程中,今天的捷径有时也会影响明天。
关于java - 对单例 "manager"对象的静态引用的缺点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32016332/