Events Dojo:主题与事件,应该考虑哪些设计考虑因素?

Events Dojo:主题与事件,应该考虑哪些设计考虑因素?,events,design-patterns,dojo,Events,Design Patterns,Dojo,我一直在不同的环境中使用Dojo,从未找到关于事件和主题的好解释。我对使用这两种机制的理解如下: 两者都是事件机制或更一般的消息机制 两者的工作原理大致相同,即通过设置回调来订阅主题/事件 事件与对象/小部件紧密耦合,例如,您需要对象或小部件的实际实例来注册特定事件的侦听器 另一方面,主题机制提供了一种更加解耦的方法,因为您可以订阅任何主题,而不知道哪个组件正在发布主题,甚至不知道主题是否将被发布 在使用Dojo开发自定义小部件时,我曾多次使用过一种方法,即允许它们发布到特定主题。其他组件将

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

  • 两者都是事件机制或更一般的消息机制
  • 两者的工作原理大致相同,即通过设置回调来订阅主题/事件
  • 事件与对象/小部件紧密耦合,例如,您需要对象或小部件的实际实例来注册特定事件的侦听器
  • 另一方面,主题机制提供了一种更加解耦的方法,因为您可以订阅任何主题,而不知道哪个组件正在发布主题,甚至不知道主题是否将被发布
在使用Dojo开发自定义小部件时,我曾多次使用过一种方法,即允许它们发布到特定主题。其他组件将订阅这些主题并做出适当的反应。但是,这会导致代码很难理解,因为当您找到订阅某个主题的代码时,您会开始怀疑是谁发布了该主题,反之亦然。目前,我倾向于让我的自定义小部件提交事件,让一个控制器监听这些事件,并将它们发送给其他小部件,这些小部件应该对这些事件做出反应

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


我很想知道这是否是对这两种机制的正确理解。我也会对任何设计考虑感兴趣,在选择两者中的一种时(或者甚至混合它们?)。任何关于这个话题的详细讨论的建议都将不胜感激。我一直在研究:但这主要描述了这两种机制是如何工作的,但对于如何构造复杂的应用程序却没有什么深入的见解。

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

事件确实与小部件本身耦合,而主题则不耦合。我通常认为是这样的:

  • 当你有主从式的结构(比如一个包含很多项的列表)时,使用小部件和事件可能是处理问题的最好方法
  • 当两个小部件彼此不相关时,主题可能是彼此交流的最佳方式
你是对的,话题让你很难知道起源是什么,但是如果你想一想,你不需要知道起源。这些主题为您提供了一个将源代码与目标代码解耦的API,这样您就不需要知道源代码了

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

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

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

define([“dojo/topic”,“dojo/_base/array”],函数(topic,arrayUtils){
var MY_TOPIC=“/MY/TOPIC”;
变量模块={
观察员:[],
通知:函数(/**String*/name,/**Integer*/age){
主题。发布(我的主题{
姓名:姓名,,
年龄:年龄
});
},
addObserver:function(/**function*/callback){
返回此.observer.push(回调)-1;
},
removeObserver:函数(/**Integer*/index){
this.observer[index]=null;
}
};
订阅(MYTOPIC,函数(数据){
arrayUtils.forEach(module.observer,function(observer){
if(observer!==null&&data.name!==undefined&&data.age!==undefined){
观察员(姓名、年龄);
}
});
});
返回模块;
});
您可以使用
notify()
函数发布(提供正确的函数参数),并使用其他函数添加/删除观察者。然后,您将使该组件成为您的唯一订户,并通知所有观察者

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


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

从设计模式和软件架构的角度来看,主题似乎是在dojo中实现flux的完美机制。找到一篇包含基本思想的文章。

你好,Johannes,欢迎来到Stack Overflow。关于你的答案有一点建议:虽然这个链接可以回答这个问题,但最好在这里包含答案的基本部分,并提供链接供参考。如果链接页面发生更改,则仅链接的答案可能无效。有关更多详细信息,请参阅。