【问题标题】:What is a good pattern for data marshaling between JS modules?什么是 JS 模块之间数据编组的好模式?
【发布时间】:2015-09-02 02:35:24
【问题描述】:

这个问题是关于在服务器上使用 JS 模块构建数据对象以供另一个模块使用的最佳实践。

我们有许多用于 Web 应用程序的模块,例如登录视图、表单处理程序,它们包含不同的数据片段,例如用户状态、应用程序状态等,我们需要将它们发送到需要特定对象的分析套件格式。我们应该在哪里映射数据? (选择我们要发送的内容、重命名键、删除不需要的值。)

  1. 在每个模块中。例如:登录知道分析及其格式 要求。
  2. 在分析模块中。现在分析必须知道 关于每个模块的源格式。
  3. 在单独的 [模块]-分析模块中。然后我们将有十几个没有太多上下文需要调试和理解的文件。

我的团队在正确设计上存在分歧。我很好奇在这个问题上是否有一些权威的声音可以帮助我们解决这个问题。

提前致谢!

例如,

var objectForAnalytics = { 
  logged_in: user.get('isLoggedIn'), 
  app_context: application.get('environment') 
}; 
analytics.send(objectForAnalytics);

这个简短的示例脚本使用来自 3 个模块的函数。它应该存在于组织良好的应用中的什么位置?

【问题讨论】:

标签: javascript user-interface design-patterns architecture


【解决方案1】:

JS 不做传统意义上的编组。

由于该语言鼓励鸭式输入并在单个 VM 中运行所有加载的模块,因此每个模块都可以简单地传递数据并让消费者选择他们感兴趣的字段。

从历史上看,编组有两个主要目的:

  1. 向另一个模块提供它期望的数据,因为 C 风格的结构和对象不支持额外的数据(通常)。
  2. 在两种语言或基于两种编译器的模块之间传输数据,这些编译器可能使用不同的内存布局、调用约定或 ABI。

JavaScript 使用 JSON 解决了​​第二个问题,但第一个问题本质上是使用字典样式的对象解决的。传递具有 1000 个键的对象与传递 2 个键的对象一样快,因此您可以(并且经常被鼓励)简单地给消费者您拥有的东西,并让他们决定他们需要什么。

这在诸如 Typescript 之类的语言中得到了进一步的加强,其中参数类型的契约只是最小的要求集。 TS 允许您传递超出这些要求的对象(通过具有其他字段),而不是仅验证您是否了解消费者在合同中声明的要求并满足要求。

当您确实需要转换一个对象时,可能是因为两个库使用不同键的相同数据,创建一个具有浅引用的新对象非常容易:

let foo = {
  bar: old.baz,
  baz: old.bin
};

这不会更改或复制基础数据,因此对原始数据(或副本)的任何更改都会传播到另一个。这不包括原始值,它们是不可变的,因此不会传播。

【讨论】:

  • 感谢您的回答。你完全正确。我挪用了术语“编组”来描述移动值以获得我们需要的格式。我们只是在处理普通的 JS 对象。我编辑了这篇文章,让它更有意义。
  • @Caqu 我认为您的问题对于 SO 来说太宽泛了。您在询问绑定应该存在于哪里,但是当您定义视图/服务/数据交换层时,它会自行解决。我能给出的最佳答案是,将这些模块绑定在一起通常会发生在相当高的级别,通常是在视图或控制器中。
  • 我明白了。我问的很广泛,因为我在许多应用程序(Ember、Sails 和 Backbone)中都有同样的问题。我喜欢你的推理,“传递一个有 1000 个键的对象和一个有 2 个键的对象一样快,所以你可以(并且经常被鼓励)简单地给消费者你所拥有的,并让他们决定他们需要什么。”这表明我们的第二个选项是这些工具的更好结构。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-07-07
  • 1970-01-01
  • 2012-06-28
  • 1970-01-01
  • 2011-03-16
  • 2020-06-06
  • 1970-01-01
相关资源
最近更新 更多