淺談mvc

pszh發表於2016-04-21

什麼才是MVC?

這是一個非新手都就會嗤之以鼻的問題,試問哪個程式猿不知道什麼是MVC,但在此我希望大家先忘記之前對MVC的所有知識,很多時候學習的第一步就是承認自己的無知,這是一個多麼重要的步驟,又是一個多麼容易遺忘的步驟啊。包括我自己也是如此,經常因為固有思維而變得傲慢而不自知,今天我們就一起重頭來學習一下MVC的歷史。

對於MVC的概念我想沒人不知,但是大部分人其實並不知道MVC的概念其實不止一個,從縱向來看,它經過了歷史上很多的演進和變種;從橫向來看,它也有許許多多不同的細微差異。即使包括後來的MVP和MVVM也都只能算它的一個變種而已

經典MVC模式

1978年,MVC模式的創始人挪威教授Trygve Reenskaug是怎麼定義MVC模式的。請看:The original MVC reports。(想看英文的可以點選去看)

這是最早期的MVC模式,其中三者的定義可以簡單的理解為:

  • Model,負責的是資料,這裡的“資料”不僅限於資料本身,還包括處理資料的邏輯。(餐廳大廚)
  • View,負責資料的表現形式,將資料及資料的變化呈現給使用者。(客戶)
  • Controller,負責使用者的輸入,將使用者的命令轉化成訊息傳遞給model或view,是一個翻譯者。(服務員)

注意先不要噴,在早期的MVC模式中,Controller的設計目的其實並不是為了隔離Model和View的,而後來這點才發現了變化。

Model & View

Model和View的關係,也可以分為兩種形式:

  1. push model:View在model上將自己註冊為資料的監聽者,model的資料發生變化時會傳送通知,view接到通知後用新資料更新自己。
  2. pull model:View負責在它需要的時候呼叫model來獲取當前最新的資料。

但不管是那種模式,model對於view都是沒有感知的,push model是在資料變化的時候簡單的傳送廣播,告之所有對該資料變化感興趣的監聽者,而pull model是view對model進行呼叫。因此在任何一種模式下,model都是不能直接操作view

這種model-view模式也就是俗稱的觀察者模式,model是被觀察者,view是觀察者,當被觀察者傳送變化的時候,通知註冊在它上面的所有觀察者。這樣設計帶來的另一個好處就在於多個view可以監聽同一個model的變化。


Controller & View

關於Controller和View的關係,Controller是繫結在View上面的,意思是使用者任何在View上的操作(例如點選按鈕等)都會呼叫Controller上的一個回撥方法。其實也意味著View是持有Controller的引用的,當使用者做相應操作時,是由View來呼叫合適的Controller方法的,而Controller對View的操作在早期概念中則不太明確。

Controller & Model

Controller是可以向Model直接通訊的。例如使用者點選了刪除按鈕,那麼Controller將使用者的這個操作翻譯成“使用者需要刪除這條資料”的訊息傳遞給Model,Model負責刪除資料,然後通知View來更新頁面以告知使用者資料的變化。

現代MVC模式

與經典MVC模式不同,很多現代系統設計中,如Apple Cocoa框架,最大的改變在於將Controller的位置放在了Model和View之間。

主要區別就在於Controller的位置變了:Controller將訊息傳遞給Model,M處理完資料後是先將資料的變化通知給C,再由C來通知View來變化檢視的。也就是說Controller變成了在Model和View之間雙向傳遞資料的中間協調者,關係變成了: View <-> Controller <-> Model 。

Model & View

Model和View之間沒有了任何關係,所有通訊都是通過Controller傳遞。

Model & Controller & View

View通過Controller向model傳遞使用者操作的訊息,而model在處理完資料後通過Controller來向View來傳遞結果。Controller從經典MVC模式中的單向翻譯官變成了雙向的中間人。

為什麼要這樣變?

其實大家都看出來了,這樣變的主要目的就是為了讓Model和View之間不再直接聯絡。從而使得三者的關係理得更清楚了。

這貨不就是MVP嗎?

瞭解MVP概念的同學可能讀到這裡可以會產生巨大的問號:這貨不就是MVP嗎?MVP裡面的Presenter不就是充當Controller和View之間的中間人嗎?

可以說Apple Cocoa這類框架使用的這種進化版的MVC確實離MVP相差很小了,可以說只差一步而已,MVP只是把三者之間的關係解藕得更厲害而已。

最後說兩句

不管是傳統的MVC,還是進化的MVC,亦或者MVP和MVVM模式,你會發現其實它們的設計理念都是一致的,逐步進化也只是為了更進一步的達到這個理念的目標,那就是:

上帝的歸上帝,凱撒的歸凱撒!

如果你沒有理解這一點,那麼用什麼模式也是混亂的;而如果你理解了這一點,什麼模式不用也是清晰的。




原文/駱駝騎士(簡書作者)
原文連結:http://www.jianshu.com/p/13c4894c5129
著作權歸作者所有,轉載請聯絡作者獲得授權,並標註“簡書作者”。

相關文章