【问题标题】:Flux - Isn't it a bad practice to include the dispatcher instance everywhere?Flux - 在任何地方都包含调度程序实例不是一个坏习惯吗?
【发布时间】:2015-07-05 21:26:56
【问题描述】:

注意:我的问题是关于包含/传递调度程序instance的方式,而不是关于模式如何有用。

我正在研究 Flux 架构,但我无法理解调度程序(实例)可能被包含在任何地方的概念......

如果我想从模型层触发动作怎么办?在我的模型文件中包含对象的 instance 对我来说感觉很奇怪......我觉得这缺少一些注入模式......

我的印象是,确切的 PHP 等价物是(感觉)可怕的类似于:

<?php
$dispatcher = require '../dispatcher_instance.php';

class MyModel {
    ...
    public function someMethod() {
        ...
        $dispatcher->...


    }
}

我认为我的问题不仅与 Flux 架构完全相关,而且更多地与 NodeJS 的“做事方式”/一般实践有关。

【问题讨论】:

  • 单例调度器是因为你想要一个地方让你的应用程序中的所有事件都流动(无论是 API 请求/响应还是用户交互)。它或多或少是event sourcing 的一种形式。
  • “在我的模型文件中包含一个对象的实例对我来说感觉很奇怪”——确实如此,因为你的模型不应该关心它。模型的目的是保存数据。

标签: node.js reactjs flux


【解决方案1】:

TLDR:

  • 不,在您的商店中传递调度程序实例并不是一个坏习惯
  • 所有数据存储都应该引用调度程序
  • 调用/消费代码(在 React 中,这通常是视图)应该只引用动作创建者,而不是调度程序

您的代码与 React 不太一致,因为您在数据存储上创建了一个公共可变函数。

在 Flux 中与商店通信的唯一方式是通过 message passing 始终流经调度程序。

例如:

var Dispatcher = require('MyAppDispatcher');
var ExampleActions = require('ExampleActions');

var _data = 10;
var ExampleStore = assign({}, EventEmitter.prototype, {

  getData() { 
    return _data;
  },

  emitChange() {
    this.emit('change');
  },

  dispatcherKey: Dispatcher.register(payload => {
    var {action} = payload;
    switch (action.type) {
      case ACTIONS.ADD_1: 
        _data += 1;
        ExampleStore.emitChange();
        ExampleActions.doThatOtherThing();
        break;
    }
  })

});

module.exports = ExampleStore;

通过关闭_data 而不是直接在商店中拥有data 属性,您可以强制执行消息传递规则。这是一个私人成员。

同样需要注意的是,虽然你可以直接调用 Dispatcher.emit(),但这不是一个好主意。

通过动作创建者有两个主要原因:

  1. 一致性 - 这是您的视图和其他消费代码与商店交互的方式
  2. 更轻松的重构 - 如果您曾经从应用程序中删除 ADD_1 操作,此代码将引发异常,而不是通过发送与任何开关语句中的任何开关语句都不匹配的消息来静默失败商店

这种方法的主要优点

  • 松散耦合 - 添加和删除功能轻而易举。商店可以通过添加一行代码来响应系统中的任何事件。
  • 复杂性更低 - 数据流的一种方法可以更轻松地环绕数据流。减少相互依赖。
  • 更轻松的调试 - 只需几行代码即可调试系统中的每个更改。

调试示例:

var MyAppDispatcher = require('MyAppDispatcher');
MyAppDispatcher.register(payload => {
  console.debug(payload);
});

【讨论】:

  • 嗨,邓肯,谢谢您的详尽回答。我同意你的观点,将调度程序传递给同样是单例的 Store 并不是一个坏习惯(实例,而不是类定义)。我更关心的是纯模型层,例如,当您的商店消费/使用特定模型、实例化它等时。由于您在答案中强调的原因,该模型需要使用调度程序。然后我认为我必须在模型构造函数中注入调度程序。谢谢。
猜你喜欢
  • 1970-01-01
  • 2010-09-11
  • 1970-01-01
  • 2017-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多