草庐IT

javascript - 帮助 "Scalable JavaScript Application Architecture"

coder 2024-05-14 原文

我正在构建一个大型 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 标记对我来说开始变得不那么有意义了,并且它开始看起来像窗口模块应该负责生成该标记---但是很多标记是“上传”特定的,并且标记有事件监听器绑定(bind)到上传模块中的函数---所以在窗口模块中没有真的很合乎逻辑......所以它开始变得非常困惑,什么是构建所有这些的最佳方式。

我还有另一种情况,问题更大。两个模块: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') 并将其指向一个函数,该函数返回一个给定类型的新 track 对象.....也许它只是不值得拥有 track是它自己的模块......因为这是我根据通知调用分配值的唯一地方。

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

请给我你的想法和建议。

谢谢。

最佳答案

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

您的问题可以归纳为:

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

No.3 是给您带来问题的原因——您希望模块是独立的,但它需要与其他模块通信才能使您的程序正常工作。

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

请注意,您的模块不应该关心另一面——四个 W

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

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

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

有多少——不应该关心它同时与多少对象交谈/收听

然后,您将整个图表与主配置连接起来。这是依赖注入(inject)背后的基本概念。

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

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

关于javascript - 帮助 "Scalable JavaScript Application Architecture",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5740156/

有关javascript - 帮助 "Scalable JavaScript Application Architecture"的更多相关文章

  1. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  2. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  3. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  4. ruby-on-rails - 迷你测试错误 : "NameError: uninitialized constant" - 2

    我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test

  5. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

  6. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

    我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

  7. ruby - 有人可以帮助解释类创建的 post_initialize 回调吗 (Sandi Metz) - 2

    我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法

  8. ruby - 安装 Ruby 时遇到问题(无法下载资源 "readline--patch") - 2

    当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub

  9. ruby-on-rails - Cucumber 是否只是 rspec 的包装器以帮助将测试组织成功能? - 2

    只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您

  10. ruby - RVM "ERROR: Unable to checkout branch ."单用户 - 2

    我在新的Debian6VirtualBoxVM上安装RVM时遇到问题。我已经安装了所有需要的包并使用下载了安装脚本(curl-shttps://rvm.beginrescueend.com/install/rvm)>rvm,但以单个用户身份运行时bashrvm我收到以下错误消息:ERROR:Unabletocheckoutbranch.安装在这里停止,并且(据我所知)没有安装RVM的任何文件。如果我以root身份运行脚本(对于多用户安装),我会收到另一条消息:Successfullycheckedoutbranch''安装程序继续并指示成功,但未添加.rvm目录,甚至在修改我的.bas

随机推荐