如何实现Javascript中介(发布-订阅)模式

如何实现Javascript中介(发布-订阅)模式,javascript,architecture,Javascript,Architecture,背景 我们有一个相当复杂的Silverlight客户端,我们正在用HTML/Javascript/CSS重写它,它构建在相同的web服务之上。实际上,我们正在移植两个Silverlight不同的客户端,它们共享一些共同的功能 我阅读了关于的文章,并计划使用建议的体系结构,特别是中介模式 由Addy描述的10000英尺模式概述: 代码分为几个小模块 模块只知道中介对象;模块不能直接与其他模块通信 中介有一个用于发布和订阅消息的简单接口 模块可以订阅消息(通过中介API),并提供回调函数 模块可以

背景

我们有一个相当复杂的Silverlight客户端,我们正在用HTML/Javascript/CSS重写它,它构建在相同的web服务之上。实际上,我们正在移植两个Silverlight不同的客户端,它们共享一些共同的功能

我阅读了关于的文章,并计划使用建议的体系结构,特别是中介模式

由Addy描述的10000英尺模式概述:

  • 代码分为几个小模块
  • 模块只知道中介对象;模块不能直接与其他模块通信
  • 中介有一个用于发布和订阅消息的简单接口
  • 模块可以订阅消息(通过中介API),并提供回调函数
  • 模块可以使用参数对象向中介发布消息,中介调用订阅消息的任何模块的回调方法,并传递参数对象
这里的主要目标之一是实现模块之间的松耦合。因此,我们可以重用两个客户端中的模块。并对模块进行隔离测试。调解人应该是我们唯一需要的全局对象,它必须是好的

但是,尽管我喜欢这个想法,但我觉得在某些情况下它过于复杂,而且我的一些团队成员不会被说服。让我举例说明:

假设我们有一个执行计算的helper函数——假设它格式化了一个字符串——并且假设这个函数应该对任何模块都可用。此功能可能属于“工具”或“帮助器”模块,然后可重用和测试

要从任意模块调用此函数,我必须发布一条消息,类似于formatString,并将输入字符串作为参数。并且helper函数已经订阅了formatString消息。但是在发布formatString消息之前,我首先必须订阅一条类似formatStringResult的消息,并使用一个可以接收结果的回调函数。一旦我得到结果,我就会取消订阅formatStringResult消息

问题

  • 中介是否应该直接在自己的接口中提供这种类型的助手功能
  • 或者我应该扩展发布接口以允许一个可选的结果参数,帮助器方法可以直接写入结果
  • 有一个额外的中介层的权衡真的值得吗 实现松耦合的好处

我非常感谢具有在“复杂”JavaScript应用程序中实现松耦合经验的开发人员的建议。

您实际上完美地描述了
BarFoos应用程序框架


我不认为调解人是你所寻找的模式,至少不是你所描述的模式。
只需考虑两个对象同时触发formatString。每个人在他们的结果中会得到什么


调解人是用来向每一个正在听的人广播事件的。发布者不希望广播请求(例如,formatString),而是希望通知其他人其自身状态的更改。请注意信息的来源和使用者是如何不同的。有一个调解人意味着这些当事人不必相互引用来进行交流,从而降低了耦合。

谢谢你的回答-只是对你关于两个对象同时触发“formatString”的观点有点怀疑:这里不涉及多线程;向中介发布消息本身不是异步的,它调用所有订阅者,然后返回。同意,我忽略了我们在浏览器环境中的事实:)但其余仍然有效:如果发布者不关心事件的结果,请使用中介通知其他对象。