OOP设计:一个对象依赖于其所有依赖项的存在
OOP design: one object dependent on the existence of ALL its dependencies
请注意,我几乎没有受过这类设计理论的正规教育,如果我对某些概念一无所知,请耐心等待。我所有的推理都来自C++的背景。我正在开发一个用于游戏引擎的基于组件的系统,这就是我提出的结构。
- 有一些组件,它们只是数据
- 存在允许访问该数据的节点
- 存在仅在节点上操作的系统
- 存在实体,其中包含这些节点、组件、系统和其他实体
非常简单,但让我们只关注组件和节点,我有一套非常严格的指导原则。
- 节点可以提供对实体内组件集合的访问
- 节点依赖于所有底层组件的存在
- 组件可以独立于指向它的任何节点而存在
- 系统只能对节点进行访问和操作
现在,这些节点和组件中的任何一个都可以随时销毁。我已经为节点实现了这一点,方法是使用一组侵入性列表来维护跨节点迭代的非所有权方法,然后它们在销毁时自动从列表中删除自己。但现在我有一个关于组件的问题。在销毁某个组件时,还必须销毁依赖该组件的所有节点。通常,当另一个对象被销毁时,需要销毁的对象的简单修复方法是所有权,即只需将节点放置在组件中或在组件析构函数中动态销毁它,但这里的节点可以引用多个不同的组件。当一个对象有多个所有者时,通常像智能指针这样的引用计数解决方案会赋予所有这些对象所有权,并在所有所有者都被销毁时被销毁,但这次不是这样。我最大的问题是,当我有一个对象,只有当所有的依赖项都存在时,我才能存在,并且在任何依赖项被破坏时,我该如何处理所有权问题。
示例:
红色是存在第二个节点所需的组件
它所依赖的任何一个组件被摧毁后的样子
显然,有多种不干净的解决方案,包括弱指针、手动删除和大量对象存在检查,但就像所有问题一样,我想知道这是否可以通过单独的设计安全地实现。同样,如果这是一个非常简单或众所周知的概念,请给我指明正确的方向。
@Jorgen G Valley-所有对象都归实体所有,因为所有对象都是在销毁包含的实体时销毁的,但节点、组件、系统和实体应该能够随时动态添加或删除。下面是一个例子。从世界实体开始,它包含一个实体,该实体是一个网格和两个向量。这两个矢量是独立更新的,但假设要将它们作为父对象,只需添加一个节点,指定一个矢量作为父对象并指定任意数量的矢量作为子对象。将节点添加到实体中会将其置于非拥有列表中,从而允许以前存在的"父"系统遍历所有"父"节点并在每个父节点上执行功能。取消绑定对象只需删除节点,但向量和网格应该仍然存在。假设您只想破坏该向量并保留网格以在另一个模型中使用,那么破坏该向量也应该破坏父节点,因为它不再引用有效的向量。
以下是一些视觉效果:
这是上面案例的一个例子。此处
下面是一个删除父节点的示例。此处
请注意,该组件之所以保留,是因为它可以在其他节点中使用,比如本例中,渲染节点正在使用它。节点的销毁填补了父系统使用的侵入列表中的空白,这意味着父系统只管理任何其他实体的父节点。
下面是一个去除矢量分量的例子。此处
在这种情况下,还必须移除依赖于该向量的所有节点,包括父节点和渲染节点。这些破坏填补了这些侵入性清单中的空白,系统仍在继续。希望这有助于说明我正在努力实现的设计。
我认为您将事情复杂化了一点。你说节点和组件可以在任何时候被销毁。这真的是真的吗?
在文本中,您将实体描述为所有者,因为您说它包含组件、节点和系统。
我的方法是,只有当拥有组件的实体被销毁时,组件才会被销毁。这意味着节点、组件和系统不需要为破坏而烦恼。它是由拥有对象实体来完成的。
编辑:如果你有这样的情况,组件、节点或系统可以在没有上覆实体被破坏的情况下被破坏,我很想听听一个例子。这本身就是一个非常有趣的问题
- C++模板来检查友元函数的存在
- 如何从C++中的依赖类型中获得它所依赖的类型
- 检查是否存在模板方法,而不依赖自动模板扣除
- 在C++的松弛记忆模型中是否存在具有依赖周期的非因果行为
- OOP设计:一个对象依赖于其所有依赖项的存在
- CMAKE:目标依赖项存在问题(add_dependency不起作用?
- 当存在许多相互依赖的项目时,Visual C++中的文件夹结构
- 如何使用type_traits生成依赖于是否存在类专用化的代码?
- 如何检查给定文件是否存在依赖项错误
- 当C++模板类中存在循环依赖关系时,修复包含顺序
- 使用发布 CRT 在调试中构建应用程序,并在提升时存在依赖问题
- 强制 cmake 选择依赖位置(如果存在多个)
- 为什么构造函数调用依赖于默认析构函数的存在?
- 尽管存在强依赖类,但设计灵活
- 对象依赖关系和处理其中一个不再存在的情况
- 基于依赖类型存在的重载
- CreateService() 调用成功,即使依赖项不存在
- GCC、Clang和IBM在如何执行依赖模板参数的名称查找方面存在分歧.哪一个是对的
- 用户界面-是否存在用于C++的跨平台GUI库(具有依赖于平台的UI和基于脚本的布局)
- 这里是否存在循环依赖