非死book:MVC模式不適用,使用Flux模式代替
非死book發現MVC模式不能滿足他們持續增長的需求,并決定采用一種不同的模式進行替代:Flux
在最近的F8會議(Hacker Way: Rethinking Web App Development at 非死book)期間,非死book的技術總監Tom Occhino說,對于足夠大型的代碼庫和大型組織,“MVC會很快變得十分復雜”,得出MVC并不適用的結論。每當嘗試添加新的功能使得代碼變得“脆弱并不可控”時系統的復雜程度成指數增長。這對于一個接手新代碼庫的開發者來說是個棘手的問題,因為他們害怕破壞所以不敢改代碼。這是MVC模式被非死book拋棄的原因。
這個問題的解決需要“將代碼通過一種更可控的方式進行組織”。Flux和React做到了這一點。Flux是一種促進應用內數據單向流動的系統架構。據Occhino介紹,React是一種用來構建“可控”和“聲明式”的web用戶接口的JavaScript框架,使得非死book可以更快的開發web應用。
非死book的軟件工程師Jing Chen補充道,MVC適用于小型應用,一旦許多模塊以及對應的視圖被添加到系統中時,系統的復雜性將爆炸性增長,如下圖所示:
這樣的應用將很難理解和調試,特別是由于模塊和視圖之間可能的雙向數據流動。Jing Chen建議下圖的Flux設計模式:
Store包括應用所有的數據,Dispatcher代替了之前的Controller,決定當Action被觸發的時候如何更新Store。當Store改變后View同樣會被更新,選擇生成一個被Dispatcher處理的Action。這確保了系統組件之間的單向數據流動。一個擁有多個Store或者View的系統,當數據只沿一條路徑流動,并且不同的Store和View不會直接相互影響的時候,可以看做只擁有一個Store和一個View。
非死book在GitHub上的文檔更加詳細的解釋了Flux, Dispatcher 和 Stores:
dispatcher是Flux應用中用于管理所有數據流動的中央樞紐,本質上是回調到store的注冊。每一個store自行注冊并提供一個回調。當dispatcher響應一個action的時候,應用中所有的store接收注冊表中action通過回調產生的有效數據。
伴隨著應用開發,dispatcher變得更加重要,因為它可以通過在特定的序列中調用注冊的回調來管理store之間的依賴。store可以通過聲明的方式其他store完成更新,之后相應的進行自身的更新。
store包含應用的狀態和邏輯。規則類似于傳統MVC模式中的model,但管理很多對象的狀態,store并不是對象的實例。store同樣類似于Backbone框架中的collection。不同于簡單管理ORM風格對象中的collection,store管理著應用特定領域內的應用狀態。
Jing Chen說,數據層在任何其他action被觸發前完成視圖的更新是很重要的。當Dispatcher存在之前沒有處理完成的action時,可以拒絕處理其它的action。這種設計方式對于有類似于更新其它視圖層這種副作用的action十分有幫助,使得代碼更加簡潔,使得新的開發者能夠更加容易得理解和調試代碼。Flux幫助非死book消除了一個通知bug,就是當用戶沒有新消息時提示用戶有新消息。
Flux TodoMVC的教程和源碼可以在GitHub上獲得。
雖然非死book可以使用任何他們認為合適的設計模式,但還有一個問題:MVC是否適用?畢竟MVC適用于很多網站。
更新。發表這篇文章之后,許多開發者在Reddit評論關于非死book使用MVC的問題。這里有一些評論,一些人認為非死book一開始濫用了MVC,一些人認為他們在做正確的事情:
giveupitscrazy:
這沒有任何意義。
首先,他們MVC圖的缺陷十分明顯。他們使用單一控制器處理多個模型,
當然他們所描述的那種設置并不有效,但同樣那也不是真正的MVC。
如果你將他們的flux圖與這樣實際的MVC圖相比較,你會得到更加清晰的認識,就是對web應用而言,MVC是適用的。
balefrost:
并且還有一個問題,就是他們的Flux圖與你的MVC圖非常相似。
他們重新定義了MVC,并且決定重新給它命名。天啊!
hackinthebochs:
看起來就像是這種架構將MVC轉變成了基于事件的。“stores”通過dispatcher進行注冊(并大概規定調用順序的依賴),同時dispatcher處理action并確保生成正確的調用鏈。這將確保適當調用順序的壓力由controller轉移到了dispatcher和store。這可以減少對于修改行為理解的重要性。
runvnc:
我只是隨便看了看,雖然我覺得我還不太清楚,但我想我理解并同意這個觀點。
根據評論看像是Jing Chen的Reddit用戶jingc09,補充說明道:
jingc09:這是一個棘手的幻燈片[擁有多個model和view,以及雙向的數據流],一定程度上是由于目前沒有對于MVC確切的共識,很多人對于MVC到底是什么有不同的想法。我們真正討論反對的是雙向數據流動,因為這樣改變會回環并產生級聯影響。
她也嘗試去闡明Flux中的Dispatcher并不是MVC中Controller的事實:
我想說明dispatcher并不承擔與controller相同的角色。dispatcher中沒有業務邏輯,并且我們在多個應用中使用相同的dispatcher代碼。dispatcher只是一個讓事件到達指定用戶的事件中心(通常是store)。但它在Flux中是重要的,因為執行的是單向的數據流動。
維基百科這樣解釋MVC中的Controller:
controller會向model發送命令來修改model的狀態(例如編輯文檔)。也可以向相關的view發送指令來改變model中view的展示(例如滾動文件)。
Jing Chen說:
dispatcher不能做這些事情,指令需要從其他地方(視圖,服務器響應,實時更新)產生并通過dispatcher傳遞。 https://github.com/非死book/react/blob/master/examples/todomvc-flux/js/dispatcher/Dispatcher.js 可以幫助解釋這一點。
根據Reddit的評論,關于MVC是什么和怎樣實現有一些爭論。
對于非死book使用MVC我們有兩種觀點:
1)第一張幻燈片看上去真的是有太多的模塊和視圖,讓人想實際是否真的存在這種情況。Fackbook使用Flux解決問題的是一個只有三個視圖的聊天應用。
2)為什么View生成的數據流在他們的MVC示例中會產生雙向的流動?并且為什么在Flux圖中View會生成Action?View不應該產生任何東西。View只是一個“視圖”,而不是其它東西。Facebbook是否濫用了MVC?
來自:http://www.zcfy.cc/article/非死book-mvc-does-not-scale-use-flux-instead-updated-2489.html