Flux:如何处理生成其他依赖对象的对象

Flux: how to deal with objects that generate other dependent objects

Context:我们正在使用 React/Alt.js 构建一个复杂的 3D "Sims-like" 网络应用程序。用户可以在 3D 场景中添加简单的对象(一个立方体),但更多时候他们会添加我们所说的 "prefab",它是基于一些用户参数的几个简单对象(15 个立方体构成一个结构)的集合(长度,高度,...)。

所以我们有一个包含所有简单对象的 ObjectStore 和 PrefabStore(它只保存用户的参数来生成预制件)。

我们只能在 React 层中生成此预制件及其对象(这样预制件渲染始终与商店中预制件的参数同步),但出于技术原因,我们需要所有这些预制件的简单对象才能真正存在于store层。换句话说,我们需要在商店中生成预制件的对象(ObjectStore,因为它是存储简单对象的地方)。

问题是where(在store层),when如何生成预制件及其所有依赖对象,以及我们应该在哪里存储生成的对象,知道:

  1. 当预制件的参数更新时,我们需要重新生成和更新对象(现有对象可以移动、旋转、完全删除)。
  2. 我们无法在 React 视图层中计算预制件生成的对象,因为我们需要在存储层中生成这些对象(因为这些对象可以与其他对象交互,当我们生成包含所有现有对象的文件时也需要它们).
  3. 生成预制件及其依赖对象是一项复杂而缓慢的任务:我们不能在每次需要渲染预制件时都调用此生成函数。此外,正如我在前面提到的那样,我们需要对生成的对象的引用,以便它们必须存在于商店中。

帮助理解什么是 prefab 和简单的 object,以及为什么我们需要 prefab 的对象存在于商店层,这是我们应用程序的屏幕截图:

我的解决方案:

  1. 在 React 组件中即时生成预制件和依赖对象。

优点:预制渲染和依赖对象始终与预制数据同步。当预制件的参数更新时,React 会自动渲染预制件并重新生成对象。

缺点:对象并不真正存在。它们不在 ObjectStore 中,所以我无法与它们交互(显示对象列表,生成包含所有对象的文件,...)。

  1. 生成预制件和依赖对象一次,然后用生成的对象填充依赖存储(ObjectStore、PrefabStore)。

优点:所有对象都存储在自己的Store中。

缺点:当你更新一个预制件时(move/rotate/resize),很难更新所有依赖生成的对象,你需要在ObjectStore中使用一堆store lsitener来确保对象与其所属的预制件同步。

  1. 即时生成预制件和相关对象,但在商店中带有记忆。 优点:从属对象总是同步的 + 对象确实存在于存储层中(不确定如何在两个不同的存储中处理此记忆:PrefabStore 和 ObjectStore)。

缺点:我不知道如何在两个不同的商店中处理记忆:预制对象的 PrefabStore(它仍然具有 position/rotation 属性)和 ObjectStore对于生成的对象。

回答这类架构问题很棘手 - 您是自己系统和领域的专家,但无论如何:

基本的通量规则是 Store 负责改变自己的状态以响应 Action。此外,还有良好的通用代码组织实践,例如低耦合和高内聚等

一个选项是:

  1. 某种预制模型对象,知道参数 一个预制件 'template' 并且有一个生成方法来创建和 return 适当的对象(也许生成方法必须将一些位置信息或其他东西作为参数)。预制模型可以在单独的代码模块中与任何商店分离。如果您愿意,generate 方法可以是一个纯函数,在它自己的模块中。

  2. Prefab Store 可以直接存储预制模型(可能是最简单的),或者只存储构建模型所需的数据。

  3. Object Store 有一个用于 ADD_FROM_PREFAB 操作的处理程序,该操作查询 Prefab 存储以获取适当的 Prefab 模型 data/instance,调用 在其上生成并最终将 returned 对象添加到其状态中。

  4. UI 然后只渲染来自 ObjectStore 的场景,而不是预制件商店(尽管预制件商店可能也用于预制件库 UI?)

通过这种方法,您可以单独对预制模型和对象生成进行单元测试,并轻松地在需要的地方重新使用它。商店代码也是相当简单的胶​​水,易于测试。而且 UI 不需要担心渲染部分的预制件。