爲何MVC不是一種設計模式

http://damoqiongqiu.iteye.com/blog/1949256html

---比較Backbone和Ext4.x在MVC實現上的差別前端

大漠窮秋git

前言

聖人云:不想作媽咪的小姐不是好碼農。github

每個碼農的心中都有一個終極理想,那就是有一天不用再Coding。設計模式

在成爲媽咪的道路上,「設計模式」被認爲是一項必備的技能。瀏覽器

所以,常常有溼主會問小僧這樣一個問題:爲何MVC不是一種設計模式呢?前端框架

對於這樣naive的問題,小僧向來是嗤之以鼻的,大家啊!圖樣圖森破!app

機緣巧合,前段時間在焦點技術大會上聽到一位大牛關於Backbone的介紹,因而小僧最近一段時間研究了一下Backbone相關的內容。框架

在《Developing Backbone Application》(戳這裏查看此書電子版)這本書上,剛好有幾段關於MVC相關的內容,看完這段內容以後,小僧忽然有醍醐灌頂之感。原來爲何MVC不是一種設計模式這個問題還真的是個問題,看起來是小僧本身執念過重了!ide

罪過罪過。

彌陀佛~~!

(淘寶的一位牛人白汀 @白汀UX 翻譯了《Developing Backbone Application》這本書,完整的在線電子版請戳這裏,小僧友情建議一下這位大牛,請注意翻譯質量,錯別字和語句不通順的問題太多了點!)

爲了讓各位道友也能領悟到設計模式裏面的一些奧妙,小僧特做此文。

稍安勿躁,讓小僧給各位溼主解說一番。

(這裏就不對着原文翻譯了,爲了方便各位道友理解,小僧總結一下其中的精髓,E文好的請點瀏覽器右上角。)

MVC的起源

1979年,Trygve Reenskaug 這位牛人在Smalltalk-80系統上首次提出了MVC的概念,最初的時候叫作Model-View-Controller-Editor。

(我擦,1979年小僧還在佛祖那兒唸經呢吧?)

1994年,Gof(Gang of Four)在《Design Patterns: Elements of Reusable Object-Oriented Software》一書中對MVC模式作了深刻的解析。

Trygve Reenskaug最初提出MVC的目的是爲了把數據(Model)視圖(View)分離開來,而後用控制器(Controller)做膠水來粘合M和V之間的關係。

很顯然,這樣作的目的是爲了實現注意點分離這樣一個更高層次的設計理念,也就是讓專業的對象作專業的事情,View就只負責視圖相關的東西,Model就只負責描述數據模型,Controller負責總控,各自協做,別總摻和到一塊兒亂成一鍋粥!

最古典的MVC實現

請注意上一小節中的兩個年份,1979年,計算機還不是屌絲能玩兒得起的東西!那時候比爾蓋茨仍是個小學生,而且他尚未輟學創辦MicroSoft,那時候人們不知道什麼是Windows,固然,也沒有什麼GUI的概念。

各位道友能夠想一想一下,黑黑的命令行,一串一串的文本字符...

嗯嗯,就是那個樣子的!

顯然,在這樣的歷史背景之下,原始的MVC模式顯然不是現在所理解的那種樣子。

在Smalltalk-80上的那個古典實現上,View和Controller都是要監聽Model的,也就是說,只要數據發生變化,視圖和控制器都會收到通知的!

也就是這個樣子的:

C和M,V和M之間都是經過Observer pattern (觀察者模式)來實現的。

對於這種古典的實現細節,請參見Martin Fowler的這篇文章

爲何GOF的23種設計模式裏面沒有MVC?

好了,到這裏應該來解釋爲何MVC不是一種設計模式這個問題了。

對於這個問題,直接引用@白汀UX 的譯文以下:

GoF (Gang of Four,四人組, 《Design Patterns: Elements of Reusable Object-Oriented Software》/《設計模式》一書的做者:Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides)並無把MVC說起爲一種設計模式,而是把它當作「一組用於構建用戶界面的類集合」。在他們看來,它實際上是其它三個經典的設計模式的演變:觀察者模式(Observer)(Pub/Sub), 策略模式(Strategy)和組合模式(Composite)。根據MVC在框架中的實現不一樣可能還會用到工廠模式(Factory)和裝飾器(Decorator)模式。我在另外一本免費的書「JavaScript Design Patterns For Beginners」中講述了這些模式,若是你有興趣能夠閱讀更多信息。

正如咱們所討論的,models表示應用的數據,而views處理屏幕上展示給用戶的內容。爲此,MVC在覈心通信上基於推送/訂閱模型(驚訝的是 在不少關於MVC的文章中並無說起到)。當一個model變化時它對應用其它模塊發出更新通知(「publishes」),訂閱者 (subscriber)——一般是一個Controller,而後更新對應的view。觀察者——這種天然的觀察關係促進了多個view關聯到同一個 model。

對於感興趣的開發人員想更多的瞭解解耦性的MVC(根據不一樣的實現),這種模式的目標之一就是在一個主題和它的觀察者之間創建一對多的關係。當這個 主題改變的時候,它的觀察者也會獲得更新。Views和controllers的關係稍微有點不一樣。Controllers幫助views對不一樣用戶的輸 入作不一樣的響應,是一個很是好的策略模式列子。

嗯嗯,知道爲何MVC沒有被GOF看成【一種】模式來對待了吧?

由於它其實是三種模式的合體

(若是之後有人問你這個問題,你能夠直接引述上面這段話,絕對高端大氣上檔次!一下就能把TA給震住!)

前端MVC與經典MVC的差別

正如前文所述,在當初提出MVC這種設計理念的歷史條件之下,基本上尚未圖形界面,固然像JavaScript這種東西也是不存在的!

可是,現在不一樣了!在現在前端框架(尤爲是各類JavaScript框架)大爆炸的背景下,幾乎全部的框架都會號稱本身具備MVC的特性。

可是,有一點請注意,現在的MVC實現與古典的MVC實現方式已經大不相同了。

下面拿Backbone和Ext來舉兩個例子。

Backbone中的MVC實現方式

對於最新版本的Backbone來講,它再也不區分出獨立的Controller,它的控制器代碼與View是寫在一塊兒的,僅僅明確區分出了Model的概念,舉個栗子:

呃,請不要在乎那些細節,看紅框的部分便可。

第一處,顯然Employee是一個Model;

第二處和第三處,顯然那EmployeeView是一個View;

第四處,setText這個方法顯然是充當Controller的角色。

很顯然,在Backbone的這種實現之下,View和Controller合體了,並無抽象出獨立的Controller這種東西。

顯然,這是古典MVC的一個變種,也就是原書做者所謂的MV*。

各位道友請仔細想一想,Backbone的這種作法有沒有道理?

Ext4.x中的MVC實現

再來看Ext4.x中的MVC實現。

從以上示例項目截圖(controller/model/view等目錄)能夠看出來(此圖來自Ext官方的說明文檔),Ext4.x採用了古典的MVC設計方案,它明確地抽象出了Controller這個類

爲何小僧堅持認爲Ext4裏面的MVC是一種過分設計?

熟悉Ext歷代版本的道友會知道,在Ext4.x以前,並無作出前面這樣的區分。

【如下純屬我的見解,僅供參考】

與Backbone相比,Ext4.x的這個設計純屬雞肋,實際上,對於帶有GUI界面的代碼來講,Controller是沒法獨立於View而存在的。

由於,在Controller裏面必定須要處處訪問View中的內容,Controller是沒法獨善其身的!

Ext4.x的這個實現爲了MVC而MVC的一個絕佳例子。

在Ext4.x中,相似爲了模式而模式的例子不勝枚舉,據小僧不懷好意的推測,這必定是Jack離開以後這幫人亂搞的結果。

這也是爲何Ext4.x的運行效率如此之差的緣由,之一。

小僧都替大家捉急有木有?!!!

對於4.x的效率問題,網上的吐槽不可勝數,各位道友可自行諮詢度娘。

爲何小僧認爲MVP/MV*纔是最佳設計理念

這裏請區分好概念,設計理念具體實現方式不是一回事。

在關於Backbone的這本書中,做者還提出了MV*和MVP (Model-View-Presenter) 的說法,不得不說,這是很是具備洞察力的看法。

其中的Presenter能夠用來與服務端交互,得到Model數據,以及把Model提交到服務端等等。

在當前MVC不少的實現裏面,與服務端的交互是寫在Model裏面的(Backbone和Ext都是這樣)。

小僧認爲,這種實現方式有待商榷,若是在Model裏面含有後臺交互的代碼,在不一樣的場景下顯然沒法達到複用Model的目的。

好比,在場景一下面你但願數據模型訪問 myApp/delUser.action,而在場景二下面你但願它訪問 myApp/daddUser.action,這種狀況你就麻煩了不是?

並且,與後臺的交互過程應該抽象成獨立的數據傳輸層,在這一點上Ext的實現略好。

所以,MV*、MVVM、MVP均可以看做MVC的現代衍生版,M和V必定要明確區分,至於要不要抽象出其它類,其它類是應該和M合體仍是應該和V合體,各位道友看着辦便可!

結語

當初提出MVC,是爲了實現關注點分離這樣一種設計理念,MVC只是實現這一理念的一種方式而已。所以,沒必要拘泥於必定要抽象出Model/View/Controller這樣的類結構。

學習模式!運用模式!超越模式!

心中無碼,一切都無碼!

彌陀佛~~!

相關文章
相關標籤/搜索