首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在游戏的情况下,单身人士是正确的选择吗?

在游戏的情况下,单身人士是正确的选择吗?
EN

Software Engineering用户
提问于 2016-12-09 09:25:41
回答 2查看 343关注 0票数 1

我一直在阅读stackoverflow和SE的顶级文章,到处都写着单身人士是多么糟糕,但我不知道如何重写我的代码。

到目前为止,我有两个绑定到gameEngine的项目,每个项目都有一个单独的类来访问内容:

  • 用于检索/创建三维空间网格实例并将其存储为活动实例的Singleton。此外,还允许注入符合接口的自己的数据类型,因此可以使用自定义属性对活动实例进行反/序列化。为同一件事从活动实例和大容量方法中添加和删除对象。
  • 主AI循环的单例:从主AI循环中添加/删除单元,注入/替换驱动AI的主StateMachineProcesses。最重要的是,我讨厌第二个例子:它需要从单例#1访问活动网格实例,因为AI的主要方面之一是对周围环境的认识,所有的世界对象都存储在1号项目的数据库中。

既然这两件事总是只有一个活跃的实例,那么单身是必要的,还是有更好的方法来重新设计整个事情呢?

EN

回答 2

Software Engineering用户

发布于 2016-12-09 09:33:58

单身是正确的选择..。

不是的。一个有状态的、全局可访问的单例(即单例设计模式)总是一个反模式,并且总是有一个更好的方法。

避免这些单例的标准方法是使用依赖注入(DI)。您仍然可以拥有某些对象的单个实例,只需将它们传递给每个对象,而不是使它们具有全局可访问性。

在您的例子中,您可以通过构造函数将3d空间网格和AI循环传递给所有其他对象,从而获得非常简单的DI。这是粗糙的,但可以满足对单例的需求,因此可以立即提高代码测试的易用性。

票数 4
EN

Software Engineering用户

发布于 2016-12-09 16:54:35

这里有几件事。

首先,如果您有一个只需要一个(或有限数量)的资源密集型组件,那么单例模式是完全合理的。如前所述,您的两个用途看起来很适合单身人士。

注意,这不等于说它们应该是全局的。这是一个不同的问题(我会讨论)。例如,它可能是明智的,有一个单一的三维网格,并明确地将它传递给您的单例AI循环。

拥有全局通常是一个不好的想法,或者更具体地说,拥有可变的全局是一个坏主意。由于您的两个组件显然都是可变的,这将影响该决定。我不会详细讨论为什么全球化是坏的,因为在‘网络上关于这个主题的评论并不少。

然而,没有经常被报道的是,为什么您可能想拥有可变的全局,尽管它们有显著的缺点。

如果没有全局值,那么必须将对对象的引用传递给每个必须访问它的函数/方法。显然,这占用了一个论证时间。在某些语言ABI(特别是一些C和C++)中,前几个参数可以在寄存器中传递。现在,如果您正在计算周期,即您有非常严格的性能约束,这可能是一个问题。您可能会不断地传递一些对大量使用的函数的引用,从而导致定期的寄存器溢出和过多的缓存丢失。

这是否足够的理由呢?是的,虽然在我的经验中是很少见的。有趣的是,我所见过的最常见的情况是在游戏引擎中,大型单点和严格的性能特性是流行的。

你应该用球体吗?这显然取决于细节。在大多数情况下,我建议不要这样做。即使你确实需要一个全球性的,不要把它当作一个,除非有必要。换句话说,将它传递给使用它作为参数的函数,除非性能要求有其他要求。那就把它记录下来。

就像软件世界中的许多事情一样,对于单子和全球化,有非常明智的经验规则,但是一个好的工程师知道什么时候弯曲它们。

票数 -1
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/337820

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档