我一直在阅读stackoverflow和SE的顶级文章,到处都写着单身人士是多么糟糕,但我不知道如何重写我的代码。
到目前为止,我有两个绑定到gameEngine的项目,每个项目都有一个单独的类来访问内容:
既然这两件事总是只有一个活跃的实例,那么单身是必要的,还是有更好的方法来重新设计整个事情呢?
发布于 2016-12-09 09:33:58
单身是正确的选择..。
不是的。一个有状态的、全局可访问的单例(即单例设计模式)总是一个反模式,并且总是有一个更好的方法。
避免这些单例的标准方法是使用依赖注入(DI)。您仍然可以拥有某些对象的单个实例,只需将它们传递给每个对象,而不是使它们具有全局可访问性。
在您的例子中,您可以通过构造函数将3d空间网格和AI循环传递给所有其他对象,从而获得非常简单的DI。这是粗糙的,但可以满足对单例的需求,因此可以立即提高代码测试的易用性。
发布于 2016-12-09 16:54:35
这里有几件事。
首先,如果您有一个只需要一个(或有限数量)的资源密集型组件,那么单例模式是完全合理的。如前所述,您的两个用途看起来很适合单身人士。
注意,这不等于说它们应该是全局的。这是一个不同的问题(我会讨论)。例如,它可能是明智的,有一个单一的三维网格,并明确地将它传递给您的单例AI循环。
拥有全局通常是一个不好的想法,或者更具体地说,拥有可变的全局是一个坏主意。由于您的两个组件显然都是可变的,这将影响该决定。我不会详细讨论为什么全球化是坏的,因为在‘网络上关于这个主题的评论并不少。
然而,没有经常被报道的是,为什么您可能想拥有可变的全局,尽管它们有显著的缺点。
如果没有全局值,那么必须将对对象的引用传递给每个必须访问它的函数/方法。显然,这占用了一个论证时间。在某些语言ABI(特别是一些C和C++)中,前几个参数可以在寄存器中传递。现在,如果您正在计算周期,即您有非常严格的性能约束,这可能是一个问题。您可能会不断地传递一些对大量使用的函数的引用,从而导致定期的寄存器溢出和过多的缓存丢失。
这是否足够的理由呢?是的,虽然在我的经验中是很少见的。有趣的是,我所见过的最常见的情况是在游戏引擎中,大型单点和严格的性能特性是流行的。
你应该用球体吗?这显然取决于细节。在大多数情况下,我建议不要这样做。即使你确实需要一个全球性的,不要把它当作一个,除非有必要。换句话说,将它传递给使用它作为参数的函数,除非性能要求有其他要求。那就把它记录下来。
就像软件世界中的许多事情一样,对于单子和全球化,有非常明智的经验规则,但是一个好的工程师知道什么时候弯曲它们。
https://softwareengineering.stackexchange.com/questions/337820
复制相似问题