有关“可扩展 JavaScript 应用程序架构”的帮助

发布于 2024-11-02 08:33:26 字数 2477 浏览 3 评论 0原文

我正在构建一个大型 JavaScript 应用程序,我决定使用 Nicholas Zakas 的可扩展应用程序架构设计: http://developer.yahoo.com/yui/theater/video .php?v=zakas-architecture

根据他的系统,模块是自我封装的并且彼此不了解...但是我在我的项目中遇到了许多实例,模块似乎有必要了解彼此关于彼此,因为它们本质上是一个更大整体的各个部分。

例如..我有三个模块:上传、窗口和管理器。

单击上传选项时,会打开一个弹出窗口,其中包含上传表单。窗口“管理器”上还有一个链接。

单击管理器链接会更新弹出窗口以显示管理工具...

...

这对我来说最有意义(伪代码):

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  )

...但这违背了理念,因为上传和管理器模块是特别是“请求”窗口模块做某事,因此他们知道这一点...

所以,我能想到的唯一其他方法是:

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  )

..但这感觉不太直观,老实说我认为它使我的代码不太清晰,因为查看上传模块的通知“点击上传选项”,根本没有告诉我点击时会发生什么。我必须在所有其他文件中寻找正在侦听它的模块......我想可以被视为一种好处,因为多个模块可能想要响应“点击上传选项”,而“需要弹出窗口”显然只能由一个模块解决。

但是当采用这种方法时,让我的上传模块传递一堆与它不知道的弹出窗口相关的 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....
};

所以 Track 模块正在执行 sandbox.listen('create-track')并将其指向一个返回新跟踪对象的函数给定的类型......也许不值得跟踪它自己的模块......因为这是我根据通知调用分配值的唯一地方。

我很想听听其他熟悉 pub/sub 架构的程序员对这个话题的看法......

请告诉我你的想法和想法。建议。

谢谢。

I am building a large javascript application and I decided to use Nicholas Zakas' scalable application architecture design:
http://developer.yahoo.com/yui/theater/video.php?v=zakas-architecture

According to his system, modules are self-encapsulated and do not know about each other... However I have come across many instances in my project where it seemed necessary for modules to know about each other, because they are in essence, the individual parts of a bigger whole.

For example.. I have three modules: Upload, Window, and Manager.

When clicking on an upload option, a pop-up window opens with an upload form. Also a link is on the window "manager".

Clicking the manager link updates the pop-up window to display admin tools...

...

It made the most sense for me to do (pseudo code):

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  )

... However this goes against the philosophy because the upload and manager modules are specifically "requesting" the window module to do something, therefore they know about it...

So, the only other way I can think of to do this would be:

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  )

.. But that feels a lot less intuitive, and honestly I think it makes my code a lot less clear, because looking at upload module's notification 'upload option clicked', doesn't tell me at all what that is supposed to happen when it's clicked.. I have to go hunting in all my other files for modules that are listening for it..... Which I guess can be viewed as a benefit, because multiple modules might want to respond to 'upload option clicked', where as 'need popup window' could only obviously be addressed by one module.

But when going that approach, it starts to make less sense to me to have my upload module be passing a bunch of html markup pertaining to a pop up window that it doesn't know about, and it starts seeming like the window module should be in charge of generating that markup--- but a lot of the markup is "upload" specific, and the markup has event listeners bound to functions within the upload module--- so having that in the window module isn't really logical... so it starts getting very confusing as to what is the best way to structure all of this.

I also have another situation which is even more problematic.. Two modules: Track and Container. The container has many tracks, and originally I just had the track functions internally part of the container module-- but as the length of code in the module started growing, I decided to separated these into their own modules for clean-code's sake... Anyway, because the container needs to know about it's tracks and to be able to reference them internally, the only way I could set this up was to do:

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....
};

So the Track module is doing a sandbox.listen('create-track') and points that to a function which returns a new track object of the given type..... Maybe it's just not worth it to have track be it's own module...... Since that is the only place where I am assigning a value based off of a notification call.

I'd love to hear what other programmers familiar with pub/sub architecture have to say about this topic......

Please give me your thoughts & advice.

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凉城凉梦凉人心 2024-11-09 08:33:26

有许多处理对象间通信的模式——这就是您真正的问题:通信。

您的问题可以归纳为:

  1. 您希望将功能分解为模块
  2. 您希望模块尽可能独立,外部链接尽可能少
  3. 模块需要在“事物的宏伟计划”中与其他模块一起工作然而,

第三点是给你带来问题的地方——你希望模块是独立的,但随后它需要与其他模块通信才能使你的程序运行。

典型的解决方案是模块向外界开放“标准化”通信通道。它不应该关心(或关心)这些通道的另一侧有多少、哪些、何处或什么对象。它仅从输入通道获取命令,并将通知发送到输出通道。一个美妙的附带好处是能够轻松地对模块进行单元测试。

请注意,您的模块不应该关心另一端 - 四个 W 是

什么 - 不应该关心它正在与(或监听)什么类或对象

在哪里 - 不应该关心另一端在哪里(服务器?或在同一个浏览器上)

哪个 - 不应该关心它正在与哪个特定对象(总统,或只是一个工人)通信 有

多少 - 不应该关心它同时与/监听多少个对象

然后您可以使用主配置将整个图表连接起来。这是依赖注入背后的基本概念。

至于管道,有几种方法/模式可以做到这一点:

  1. 事件和处理程序
  2. 发布/订阅
  3. IOC/DI 容器
  4. 上述组合

There are a number of patterns that deal with inter-object communications -- and that is what your real problem is: communication.

Your problem can be distilled into:

  1. You want functionalities to be broken down into modules
  2. You want modules to be as self-contained as possible, with as few links outside as possible
  3. Modules need to work with other modules in a "grand scheme of things" however

No.3 is what was giving you issues -- you want modules to be independent, but then it need to communicate with other modules in order for your program to work.

A typical solution will be for the module to open up "standardized" communication channels to the outside world. It should not care (or matter) how many, which, where, or what objects are on the other side of those channels. It just takes commands from input channels, and sends notifications to output channels. A wonderful side-benefit is ability to unit-test the module easily.

Notice that your modules should not care about the other side -- the Four W's

what -- shouldn't care what classes or objects it is talking to (or listening to)

where -- shouldn't care where the other side is (server? or on the same browser)

which -- shouldn't care which paticular object it is communicating with (the president, or just a worker)

how many -- shouldn't care how many objects it is talking to/listening to simultaneously

Then you wire the whole graph up with a master configuration. This is the basic concept behind Dependency Injection.

As for the plumbing, there are a few ways/patterns that this can be done:

  1. Events and handlers
  2. Publish/subscribe
  3. IOC/DI container
  4. Combo of above
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文