如果“ResourceManager”类被认为是不好的,还有什么select?

我正在听到相互矛盾的意见,例如:

  • “专用管理器类几乎从来都不是正确的工程工具”
  • “专门的管理人员class级(当前)是拥有数千资源的大型项目的最佳方式”

我们来看一个具有以下function的传统ResourceManager类:

  • 加载资源(纹理,audio,3D模型等)
  • 通过保持caching确保资源只加载一次
  • 引用计数资产以确定它们是否可以被释放
  • 隐藏实际资产来自哪里(例如,可以是每个资产一个文件,或者一个包文件中的所有资产,或甚至可以通过networking加载资产)
  • 可以在不重新启动程序的情况下重新加载资源,这对于在游戏中工作的艺术家非常有用。

我们还假设这些ResourceManager对象不是单例,而是通过dependency injection来传递“singletons is bad”参数

那么就有“使用工厂”或“称之为工厂”的说法。 我的问题是,是的,这是一个工厂,但它也是一个caching和一个reloader(缺乏一个更好的词)。 调用它是一个工厂没有正确描述它,如果我使它成为一个适当的工厂,那么caching和重新加载得到实施?

我同意“经理”类经常是一个糟糕的体系结构的症状,但在这种特殊情况下,它如何进行重构,仍然保留所有的function ? 这是一个“经理”类实际上是适当的情况吗?

我认为问题不在于这是一个糟糕的devise。 问题在于名字“经理”是不重要的,像“更新”和“过程”和“演员”。 对于试图理解这个系统的人来说是没有帮助的,如果你有其他的类对资产进行一些操作的话,这会造成混乱。

但是,以有效传达目的的方式命名事实确实非常困难 。 大多数系统太复杂,不能用名字来表示。 你所能做的最好的办法就是试着缩小这个具体的想法是什么使得这个课程具有凝聚力,其他课程还需要有什么明显的不同,并且select一个适合的独特词汇。

恕我直言,一个好名字的最重要的特点是,它是在人们会看到它(代码库)的上下文中是独一无二的,而且很容易记住。 testing应该是你可以和熟悉代码的队友进行对话,而不必明确你所指的是什么。 如果您需要编写参考文档,这也将有所帮助。

最后,考虑一下如果你不能形容这个凝聚力的想法,那么它可能不是很有凝聚力。 例如,您可以分开AssetCache中的caching和引用计数,并将加载保留在AssetLoader中。 但这真的取决于代码是多么复杂和交织在一起。

但是如果你的资产管理器有足够的凝聚力,而你的游戏中没有任何东西是资产管理,那么它可能是一个非常好的名字。

“我在一个地方做这个,还是我做了很多?

加载逻辑通常集中到一个单一的访问点,因为它往往只在应用程序中的关键点运行,我们试图尽快避开它。 这通常发生在应用程序启动,游戏级别启动,或当玩家的世界位置需要加载一个新的块来保持体验无缝。 考虑到这是一个批处理过程(无论是在一个大块还是很多小块中并不重要),使用一个方法或一组方法来调用这个过程是合理的。

在大多数平台上,加载是asynchronous的,所以你实际上别无select,只能保持加载和其他应用程序逻辑分离的代码stream,另一个原因是将资源管理function抽象到他们自己的类中。

最后,有几点需要考虑:

与例如相比,资源加载不经常运行。 游戏逻辑,那么值得为你的个人游戏对象增加复杂性呢? 游戏对象通常保持尽可能轻,仅用于模拟过程中需要的东西。

一个对象是否应该为自己的创造和毁灭负责? 这会在实体管理中造成重大的麻烦。 如果你期望一个对象执行它自己的创建过程(包括获取资源依赖),那么它也将有自我毁灭的责任。 这可能会导致悬空/空指针,所以真的必须从外部管理。 看到这个答案更详细地概述了这个问题。


PS除了通常的“单身人士是可怕的”types的论点(这是非常教条),你有没有看到一个反对ResourceManagers一个很好的论点? “专门的管理人员class级几乎从来都不是正确的工程工具”, 对于这个具体的案例根本就没有任何争论。