域驱动设计是否适合游戏?


10

我刚刚阅读了有关Domain模型的知识,因为我一直在开发一种游戏,该游戏的类仅包含数据(很少的行为/方法),因此它给我带来了启发。我将处理这些类的工作分配给了经理……现在我的经理看起来像是上帝的对象。我应该处理逻辑的游戏对象只是一个贫血领域模型。

我当前的设计模式是在Singleton中,我想进行一些重新编码以将这些内容发布出来。我从未在游戏上看到DDD(到目前为止),但这是一个好方法吗?我只是一个新手程序员(不喜欢游戏开发人员),所以我想在游戏变得过于肿以至于无法重新设计之前,了解有关良好架构的更多信息。


2
我可以说流行的游戏设计是组件架构。面向数据的设计是一种在游戏引擎的最前沿发挥作用的新设计(这实际上意味着,如何将数据放置在内存中实际上是最高的设计关注点)。但是我不能在视频游戏中谈论域驱动设计..因此,仅是一句话。
詹姆斯

游戏不是商业应用程序。商业应用程序(DDD / CQRS)中的声音体系结构绝对不是游戏中的声音,反之亦然。为什么不研究装饰器模型或组件模型?这些对于游戏是“好”的,并且可以减轻您的单例问题-即使说单例通常在游戏中也不错;特别是在进行独立开发时。专心完成某件事,否则您将像我一样拥有出色的建筑,但没有游戏。
乔纳森·迪金森

谢谢你的建议。我将阅读有关组件设计的内容。即使设计不是很好,我也会完成我正在开发的游戏。我今年11月有个截止日期。我删除了Singleton的概念,并将模块注入需要它的对象。我想现在就足够了,但是我需要学习更多。
西尔菲德(Sylpheed)

Answers:


12

在您发表文章之前,我从未听说过域驱动设计。快速浏览几个参考资料- 似乎在这里这里 -似乎只是我在大学里教过的90年代传统的面向对象编程方法的一个奇特的名字,在那里您尝试为出现的每个名词编写类在这种情况下,您尝试使用软件进行建模,以使软件的结构似乎遵循实际概念的结构。

因此,我对此的回答是,这不是“好”。通常这是一个合理的起点,但是随着您的前进,事实证明这是不够的。您很少会在一个软件中只有一个域,而是几个不同的域-例如,您可能拥有游戏的域(世界,角色,物品),渲染器的域(着色器,网格,材料),输入域(文件系统,网络,键盘和鼠标),以及这些域重叠且相互影响的问题。通常,在将两个域连接在一起的过程中,您会意识到实际上存在一个需要更改的依赖项,这意味着您的一种表示形式变得比负担多于帮助。

一个模糊的示例可能是控制台上的数学库和您的游戏角色。您的数学库将需要一个大型数据列表,然后在该列表上执行一条指令,以高效运行。您的游戏角色每个都有各自的顶点数据集,用于渲染和动画等。现在,您如何从每个角色中获得一长串所有顶点数据的列表,以便能够一次性处理?您可以执行慢速复制操作,或者可以重构字符,以使它们的数据更易于由数学库处理-但随后您的一个域崩溃了,倾向于使用另一个域。

就个人而言,我非常警惕任何类似于“无论驱动设计”的标签。软件的范围太广,太复杂,以至于无法采用一种千篇一律的方法来创建它。相反,当尝试编写最好的软件时,我会尝试退回SOLID原则。这些使您可以很好地了解代码的质量,而不必保证可以遵循并神奇地获得好的代码的灵丹妙药。不幸的是,如果没有这种附属的方法,在学习如何遵循这些准则之前需要大量的经验,这可能就是为什么很多人喜欢这种方法的原因。

关于具有贫乏类和管理器对象的问题,这通常是介绍性的面向对象课程中涉及的内容,并且实际上并不需要您遵循任何特殊方法来“修复”它。(如果您只是刚开始,您可能想读一本有关面向对象程序设计的书。)类是状态和行为的结合,其中行为修改了该状态,这被称为封装。通常,您尝试尽可能多地封装,这意味着状态应由对象本身(并且仅该对象)操纵。仅对于无法在类内建模的行为,才将其委派给外部类,例如管理器,这就是为什么通常将管理器类的存在视为不良编写的面向对象代码的标志的原因。

我当前的设计模式是在Singleton中,我想进行一些重新编码以将这些内容发布出来。

我不知道那句话是什么意思。设计模式是编写程序一小部分的众所周知的方法。您将没有“当前”的设计模式,也不会影响程序的其余部分。对于初学者来说,这些模式对于使您走上正确的道路很有用,而对于专家而言,它们更像是一种交流常见代码情况的方式。但是,有一件事很重要:单例几乎总是一个坏主意,您应该尽可能避免它们。您可以在该站点上以及Stack Overflow上找到许多关于单例的意见,但这是一个实用的问题,其答案可以帮助您避免需要它们。


好吧,让我稍微改变一下这个问题。领域模型和领域驱动的设计之间有区别吗?我对域模型的想法是,一个类应该能够处理自身,而不必尽可能依赖控制器/管理器。我目前的设计无法达到这个目的。我可能误会了一些东西。因此,在RPG游戏中,我的玩家类具有自己的领域,并且由技能,物品等不同领域组成
。– Sylpheed

是的,一个类应该能够在不依赖控制器/管理器的情况下处理自身,但这与域模型无关,而仅仅是面向对象编程的一种标准方法。目前尚不清楚您可能会误解什么,因为我不知道您为什么拥有这些经理类。
Kylotan '10 -10-10

如果没有管理器或查询对象的类,我看不到如何使模块正常工作。例如,我有一个任务模块。为了使我能够访问正确的任务,我必须向经理查询。那么,如何在没有经理的情况下解决这个问题?
西尔菲德(Sylpheed)

什么是“正确”的追求?经理怎么知道什么是对的?我的猜测是,做出此类决策的逻辑会依靠其他对象来做出决策,而这些其他对象更适合此功能。
Kylotan

好吧,现在我的经理经过一些清理后就像一个仓库一样。例如,我有10个实时任务。我正在通过ID访问这些任务,以便于检索。因此,我的玩家有一个任务组件(经理),我将从那里访问任务。仍然是玩家控制着他可以执行的任务。这是一个坏主意吗?
西尔菲德(Sylpheed),

6

范例

在撰写此答案之时,此处发布的其他答案都是错误的。

而不是问域驱动设计是否适合游戏。您应该询问“域建模”是否适合游戏。

域建模是否适合游戏?

答案是:有时候绝对很棒。但是,如果您要创建实时游戏,例如平台游戏或FPS或其他(很多游戏),则不会。它不一定非常适合那些系统。但是,可能存在那些在其中实施域模型模式有效的游戏的系统。

正如其他人在这里提到的那样,由于充分的理由,组件实体框架往往非常受欢迎。但是,在游戏开发文化中,似乎显然缺乏分层架构。同样,这是有充分的理由的,因为大多数人要开发的游戏只是改变实体上的状态,而让紧急后果成为游戏。

所有软件都不是您要编写的软件。有些与其他完全不同。

领域建模效果良好的领域示例包括纸牌游戏,棋盘游戏和其他类型的事件驱动系统。

以时间增量作为核心领域概念确定的以X帧速率运行且具有移动等特性的游戏可能不太适合。在这种情况下,我们的“域”通常是如此简单,以至于不需要域建模。碰撞检测,新实体的产生,力对现有实体的影响等往往涵盖了大多数游戏玩法。

但是,随着事情变得复杂,您确实开始看到开发人员在其实体中实现域模型以处理某些类型的行为和计算。

游戏架构中的领域模型模式

您的游戏引擎(例如Unity3D)通常是面向组件实体的。在平台游戏中,您可能会为角色创建一个实体,并且其状态会不断发生变化以更新位置等。

但是,在事件驱动型游戏中,组件实体框架的角色更有可能只是作为用户界面而存在。您最终得到了分层的体系结构。

UI将游戏状态呈现给用户。用户与UI交互,从而触发服务层中的命令。服务层与域对象进行交互。域对象引发域事件。事件侦听器听到事件并触发UI中的更改。

UI>服务层>域模型

简而言之,最后是带有服务层实现的model-view-controller。

使用此体系结构,您将获得具有事件驱动界面的完全可单元测试的游戏核心(这在游戏开发文化中是罕见的,并且可以显示出来)。

好吧,什么是DDD?

领域驱动设计专门是一种文化/运动,它着重于用于了解领域的分析模式,以便您实际上是在构建正确的事物,然后通过实现模式来使您能够实现代表模型的模型层。使用您语言的习语在领域模型中定义概念。DDD来自一个使用复杂域的社区,并且一直通过关注域建模来寻求方法来管理其应用程序中的高复杂性。

如果您的目标只是开始编码,使用系统然后弄清楚以后要构建什么,等等,那么DDD的效果就不好。它假设存在或多或少的域。因此,如果您不知道自己的游戏将会是什么。那么,它将无法正常工作。


1
感谢您的见解。我大概在三,四年前就知道了。那时(5年前),我一直很幼稚,因为我一直试图使“设计模式”适合我所有的问题。学习这些“模式”和体系结构很有帮助,因为它给了我更多选择。我总是坚持“足够地”抽象我的代码部分,以使设计人员(非常重要),单元测试和未来的机制变得容易。过度使用该架构使其很难使用,我了解到了这种艰难的方式。现在,我已经利用基于组件的体系结构来适应我的编码风格。固体ftw。
西尔菲德(Sylpheed)

3

不,我认为DDD或任何其他“流行词”体系结构对游戏而言真的不是很好。除了“组件系统”外,在这里似乎真的很流行。

当我听到这样的问题和讨论时,我想起了这个网站。考虑各种体系结构流行语通常比实际设计和编写自己的应用程序要好。


1
+1用于“实际设计和编码自己的应用程序”。这些模式是我的指导方针和思想挑衅者,仅此而已。更改问题以使其适合解决方案是错误的选择。
乔纳森·迪金森

-1

是的,但您应该适应。

使用DDD时,您将获得每个域的模块化和单一责任。但是其他任何事情都会使事情变得复杂。

在这里查看我的答案


您可能想稍微扩展一下答案(涵盖答案的主要部分),因为现在它是仅链接的答案(即使它指向另一个堆栈交换站点)。
Vaillancourt
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.