pat*_*ick 11 javascript design-patterns publish-subscribe
我建立一个大型的JavaScript应用程序,我决定使用尼古拉斯Zakas的可扩展应用程序的架构设计: http://developer.yahoo.com/yui/theater/video.php?v=zakas-architecture
根据他的系统,模块是自封装的,彼此不了解......但是我在项目中遇到了很多实例,模块似乎需要彼此了解,因为它们本质上是个体整体的一部分.
例如..我有三个模块:上传,窗口和管理器.
单击上载选项时,将打开一个带有上载表单的弹出窗口.窗口"manager"上也有一个链接.
单击管理器链接会更新弹出窗口以显示管理工具...
...
它对我来说最有意义(伪代码):
upload module:
upload option click --> sandbox.notification('need pop up window', [...html markup for form...])
manager module:
manager link click --> sandbox.notification('need pop up window', [...html markup for admin tools...])
window module:
sandbox.listen('need pop up window') --> calls createPopUpWindow( passed in html markup )
Run Code Online (Sandbox Code Playgroud)
...然而这违背了哲学原因,因为上传和管理器模块专门"请求"窗口模块做某事,因此他们知道它...
所以,我能想到的另一种方法是:
upload module:
upload option click --> sandbox.notification('upload option clicked', [...html markup for form...])
manager module:
manager link click --> sandbox.notification('manager link clicked', [...html markup for admin tools...])
window module:
sandbox.listen('upload option clicked') --> calls createPopUpWindow( passed in html markup )
sandbox.listen('manager link clicked') --> calls createPopUpWindow( passed in html markup )
Run Code Online (Sandbox Code Playgroud)
..但是,感觉少了很多直观,而且老实说,我认为它使我的代码少了很多明确的,因为看着上传模块的通知"上传选项点击",并没有告诉我在所有什么是应该当它发生点击..我必须在我的所有其他文件中搜索正在监听它的模块.....我猜这可以被视为一个好处,因为多个模块可能想要响应'上传选项点击',其中因为"需要弹出窗口"显然只能通过一个模块来解决.
但是当采用这种方法时,让我的上传模块传递一堆关于它不知道的弹出窗口的html标记对我来说开始变得不那么有意义了,它开始看起来像窗口模块应该是负责生成该标记---但是很多标记都是"上传"特定的,并且标记具有绑定到上传模块中的函数的事件监听器---因此在窗口模块中具有该标记并不是真正合乎逻辑的. ..所以它开始变得非常混乱,什么是构建所有这一切的最佳方式.
我还有另一种情况甚至更成问题.两个模块:Track和Container.容器有许多轨道,最初我只是在容器模块的内部部署了轨道功能 - 但随着模块中代码的长度开始增长,我决定将它们分离成自己的模块,以便清洁代码.无论如何,因为容器需要知道它的轨道并且能够在内部引用它们,我能设置它的唯一方法是:
containerObject = function(name) {
this.name = name;
this.video_track = {'name': 'video', 'markup': sandbox.notification('create-track', 'video')}
this.audio_track = {'name': 'audio_1', 'markup': sandbox.notification('create-track', 'audio')}
....etc....
};
Run Code Online (Sandbox Code Playgroud)
因此Track模块正在执行sandbox.listen('create-track')并将其指向一个函数,该函数返回给定类型的新轨道对象.....也许它不值得拥有跟踪它是自己的模块......因为这是我根据通知调用分配值的唯一地方.
我很想听听其他熟悉pub/sub架构的程序员对这个话题的看法......
请告诉我你的想法和建议.
谢谢.
Ste*_*ung 11
有许多模式可以处理对象间通信 - 这就是你真正的问题所在:沟通.
你的问题可以归结为:
No.3是给您带来问题的 - 您希望模块独立,但是它需要与其他模块通信才能使您的程序正常工作.
典型的解决方案是模块向外界开放"标准化"通信渠道.它不应该关心(或问题)那些通道的另一侧有多少,哪个,哪里或哪些对象.它只接收来自输入通道的命令,并向输出通道发送通知.一个很好的副作用是能够轻松地对模块进行单元测试.
请注意,您的模块不应该关心另一方 - 四个W
什么 - 不应该关心它正在谈论什么类或对象(或听)
在哪里 - 不应该关心对方在哪里(服务器?或在同一浏览器上)
哪个 - 不应该关心它与哪个特定对象沟通(总统,或者只是一个工人)
多少 - 不应该关心它同时说话/听多少个物体
然后使用主配置连接整个图形.这是依赖注入背后的基本概念.
至于管道,有几种方法/模式可以做到: