events - Dojo:主题与事件,应该考虑哪些设计注意事项?

标签 events design-patterns dojo

我一直在各种环境中使用 Dojo,但从未找到关于事件与主题的良好解释。我对使用这两种机制的理解如下:

  • 两者都是事件或更普遍的消息机制。
  • 两者的工作原理大致相同,都是通过设置回调来订阅主题/事件。
  • 事件与对象/小部件紧密耦合,例如,您需要对象或小部件的实际实例来注册特定事件的监听器。
  • 另一方面,主题机制提供了一种更加解耦的方法,因为您可以订阅任何主题,而无需知道哪个组件正在发布该主题,甚至根本不知道该主题是否会发布。

我在使用 Dojo 开发自定义小部件时使用过几次的方法是让它们发布到某些主题。其他组件将订阅这些主题并做出适当的 react 。然而,这会导致代码难以理解,因为当您找到订阅某个主题的一段代码时,您开始想知道谁在发布该主题,反之亦然。目前,我倾向于让我的自定义小部件提交事件,并让 Controller 监听这些事件,并将它们分派(dispatch)到应对这些事件使用react的其他小部件。

因此,在第一种方法中,主题机制是小部件之间的粘合剂,但它是分散的,这使得根据我的经验很难长期维护代码。在第二种方法中, Controller 类(遵循 MVC 模式)是粘合剂,它集中事件处理。

我有兴趣知道这是否是对这两种机制的正确理解。我也对选择两者之一(或什至混合它们?)时应考虑的任何设计考虑感兴趣。任何有关该主题的详细讨论的指示也将不胜感激。我一直在看:http://dojotoolkit.org/documentation/tutorials/1.9/events/但这主要描述了两种机制的工作原理,但对如何构建复杂的应用程序几乎没有提供任何见解。

最佳答案

我对主题和事件的想法与您完全相同。由于 JavaScript 是事件驱动的,因此两者当然都是事件驱动的(就像您在第一点中所描述的那样)。

事件确实与小部件本身耦合,而主题则不然。我通常将其视为以下内容:

  • 当您具有主从结构(例如包含许多项目的列表)时,使用小部件和事件可能是解决问题的最佳方法。
  • 当两个小部件彼此无关时,主题可能是彼此之间沟通的最佳方式。

你说得对,主题让人更难知道起源是什么,但如果你想一想,你就不需要知道起源。这些主题为您提供了一个 API,可将源与目标解耦,使您无需了解源。

因为这两个小部件是不相关的(这是我遵循的方法,之前描述过),所以在维护代码时通常不需要知道来源是什么。

您需要的是一个编写良好的 API,并确保作为目标的源都遵循它。如果 API 发生更改(代码维护),您可以使用 IDE 找出正在发布/订阅的小部件(例如通过搜索主题名称)并确保每个小部件都已更新。

您还可以选择封装发布/订阅行为并通过创建如下模块来提供更高级别的 API:

define([ "dojo/topic", "dojo/_base/array" ], function(topic, arrayUtils) {
    var MY_TOPIC = "/my/topic";

    var module = {
        observers: [],
        notify: function(/** String */ name, /** Integer */ age) {
            topic.publish(MY_TOPIC, {
                name: name,
                age: age
            });
        },
        addObserver: function(/** Function */ callback) {
            return this.observers.push(callback) - 1;
        },
        removeObserver: function(/** Integer */ index) {
            this.observers[index] = null;
        }
    };

    topic.subscribe(MYTOPIC, function(data) {
        arrayUtils.forEach(module.observers, function(observer) {
            if(observer !== null && data.name !== undefined && data.age !== undefined) {
                observer(name, age);
            }
        });
    });

    return module;
});

您使用 notify() 函数(提供正确的函数参数)进行发布,并使用其他函数添加/删除观察者。然后,您将使该组件成为您的唯一订阅者,并使其通知所有观察者。

这样你就不需要了解主题,而且 API 是统一的。您只需确保回调正确使用参数即可。要维护您的代码,您只需更改高级 API 并查找使用此高级组件的模块。由于它位于 require() 函数中,因此更容易检测到。

当我使用主题时,我通常会创建一个像这样的高级 API(可能会根据它的使用情况而有所改变)。但我认为所表达的观点很明确,更改主题和修改发送的数据更容易。

关于events - Dojo:主题与事件,应该考虑哪些设计注意事项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21453627/

相关文章:

forms - Symfony2 (>= 2.3) : How to listen to parent form event from child?

javascript - 元素输入上的 JQuery 自定义事件处理程序

c++ - 试图关注 QButtonGroup 中的所有按钮

javascript - DOJO 工具提示给出 "Uncaught TypeError: object is not a function "

c++ - 在事件驱动/异步框架中使用第 3 方库的回调(无文件描述符)

java - 处理复杂条件评估的设计模式

java - 状态模式java

c# - 字符串操作模式(C# 或其他语言)

node.js - 如何使用 nodejs 进行 dojo 构建?

javascript - 当我移至其他页面时,Dijit 按钮不起作用