2011-04-21 84 views
11

我建立一個大型的JavaScript應用程序,我決定使用尼古拉斯Zakas的可擴展應用程序的架構設計: http://developer.yahoo.com/yui/theater/video.php?v=zakas-architecture幫,帶「可擴展的JavaScript應用程序體系結構」

根據他的系統,模塊是自封裝的和做的不瞭解彼此......但是我在我的項目中遇到過很多情況,模塊之間似乎有必要相互瞭解,因爲它們本質上就是更大整體的各個部分。

例如..我有三個模塊:上傳,窗口和管理器。

點擊上傳選項時,彈出窗口打開並顯示上傳表單。還有一個鏈接在窗口「經理」上。

點擊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 ) 

...然而,這違背了哲學,因爲上傳和管理器模塊是專門「請求」窗口模塊做某事,因此他們知道它...

所以,唯一的其他方式我能想到的要做到這一點是:

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標記的意義​​不大,它開始看起來像窗口模塊應該負責生成該標記---但許多標記是「上傳」特定的,並且標記具有綁定到上傳模塊內的功能的事件監聽器---因此在窗口模塊中具有該功能不是'這實際上是合乎邏輯的......所以它開始變得非常混亂,關於構建所有這些的最佳方式是什麼。

我也有另一種情況,這是更成問題..兩個模塊:軌道和集裝箱。容器有很多軌道,最初我只是將內部跟蹤函數作爲容器模塊的一部分 - 但隨着模塊中代碼的長度開始增長,我決定將這些內容分離到它們自己的模塊中以實現乾淨代碼。反正,因爲容器需要知道它的軌道,並能在內部引用它們,我可以設置此的唯一辦法就是要做到:

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

所以跟蹤模塊做了sandbox.listen ('create-track'),並指向一個函數,該函數返回給定類型的新軌道對象.....也許它是不值得的軌道是它自己的模塊......因爲那是這是我根據通知呼叫分配價值的唯一地方。

我很想聽聽熟悉的pub/sub架構的其他程序員不得不說這個話題......

請給我你的想法&建議。

謝謝。

+0

一個相當簡單的實現,可以在這裏找到相當接近這個講座:https://github.com/aranm/scalable-javascript-architecture – 2012-05-29 06:00:45

+0

在這個舊帖子中發揮了作用,它對我來說非常有用,它可以鏈接到[t3js](http://t3js.org/),一個由N. Zakas創建的「爲代碼提供核心結構的極簡JavaScript框架」和他的團隊直接。 [這裏](https://www.box。com/blog/introduction-t3-enabling-large-scale-javascript-applications /)Zakas自己在幾天前介紹它的博客文章。希望這也會證明有用。 – Nobita 2015-04-17 18:59:39

回答

11

有很多處理對象間通信的模式 - 這就是你真正的問題所在:溝通。

你的問題可以概括爲:

  1. 你想要的功能被分解成模塊
  2. 你想要的模塊是作爲外自成體系越好,以儘可能少的環節儘可能
  3. 模塊需要與其他模塊一起使用「事物的宏偉計劃」,然而

第3號是什麼給你的問題 - 你想模塊是獨立的,但它然後它編輯與其他模塊進行通信,以便您的程序正常工作。

一個典型的解決方案是模塊向外界開放「標準化」通信渠道。它不應該關心(或重要)在這些渠道的另一端有多少個,哪個,哪個或哪些對象。它僅從輸入通道接收命令,並將通知發送到輸出通道。一個奇妙的副作用是能夠輕鬆地對模塊進行單元測試。

注意,你的模塊不應該關心的另一面 - 四W公司

什麼 - 不應該關心什麼類或對象,正在與(或收聽)

哪裏 - - 不應該關心那裏的另一面是(服務器或在同一個瀏覽器?)

它 - 不應該關心哪些paticular對象時,它與(總統,或只是一個工人)

通信多少 - 不應該關心多少物體它正在同時通話/收聽

然後,您將整個圖形連接到主配置。這是依賴注入背後的基本概念。

至於管道,有幾個方法/模式,這是可以做到:

  1. 事件和處理程序
  2. 發佈/訂閱
  3. IOC/DI容器
  4. 的上述組合