最近 MVC (Model-View-Controller) 和 MVVM (Model-View-ViewModel) 在微軟圈成為顯學,ASP.NET MVC 和 WPF 的 Prism (MVVM Framework) 功不可沒,MVC 和 MVVM 在概念上都是基於分層的,將呈現 (presentation) 與資料 (data) 分開的設計架構,M 和 V 基本上不是問題,但將這兩個整合的中間這層可就有很多的學問,另外,除了 MVC 和 MVVM 外,還有一個叫做 MVP (Model-View-Presenter) 的架構,這三個的設計概念非常類似,很容易會讓人傻傻分不清楚 ...
最近 MVC (Model-View-Controller) 和 MVVM (Model-View-ViewModel) 在微軟圈成為顯學,ASP.NET MVC 和 WPF 的 Prism (MVVM Framework) 功不可沒,MVC 和 MVVM 在概念上都是基於分層的,將呈現 (presentation) 與資料 (data) 分開的設計架構,M 和 V 基本上不是問題,但將這兩個整合的中間這層可就有很多的學問,另外,除了 MVC 和 MVVM 外,還有一個叫做 MVP (Model-View-Presenter) 的架構,這三個的設計概念非常類似,很容易會讓人傻傻分不清楚 ...
我們先來看各個架構的設計原則好了。
首先是 MVC,顧名思義,MVC 是將 Model, View 和 Controller 分離,讓彼此的職責 (responsibility) 能夠明確的分開,這樣不論是改 M, V 還是 C,都可以確保另外兩層可不用做任何修改,同時這樣的分層也可以加強程式的可測試性 (testability),View 和 Model 基本上是相關的,但它們並不會有直接的相依關係,而是由 Controller 去決定 Model 產生的資料,然後丟給 View 去做呈現,也就是說,Controller 是 Model 和 View 之間的協調者 (coordinator),View 和 Model 不能直接溝通,以確保責任的分離。而 Controller 可以只是一個繫結 Model 和 View 的小類別,也可以是大到包含 Workflow, Enterprise Services 或是做為外部系統的 Proxy Services 等的邏輯系統,MVC 各元件是可以分離的組件,也可以是分離的系統 (當然要設計一些機制在相互溝通)。
(source: Wikipedia - http://en.wikipedia.org/wiki/Model-view-controller)
再來是 MVVM,MVVM 的架構一樣是 M, V 分離,但中間是以 VM (ViewModel) 來串接,這個 ViewModel 比較像是 View 的一個代理程式,它負責直接對 Model 做溝通,而 View 可以透過一些機制 (ex: Events, Two-way Databindings, ...) 來和 ViewModel 溝通以取得資料或將資料拋給 Model 做存取等工作,ViewModel 也可以作為和外部系統的代理程式,例如 Web Service 或是 REST Service 或是 Enterprise Services 等等,不過它和 MVC 不同的地方,就是 ViewModel 和 View 的黏合度比較高,因為 View 必須要透過 ViewModel 才可以取得 Model,而 ViewModel 又必須要處理來自 View 的通知訊息,所以雖然職責一樣分明,但是卻不像 MVC 那樣可以擴展到整個系統元件都能用。如果 MVVM 要和 MVP 比較的話,MVVM 會比 MVP 更靈活一點。
Source: http://csharperimage.jeremylikness.com/2010/04/model-view-viewmodel-mvvm-explained.html
接著是 MVP,MVP 一樣也是職責分明,且 Model 與 View 分離的架構,但是這個 P (Presenter) 和 ViewModel 就很類似,不過就如同 Presenter (主持人) 這個字所代表的意義,所有主控 View 呈現的工作,都是由 Presenter 來做,而 View 本身只是 Presenter 所要使用的舞台而已,所以 View 原則上會相依於 Presenter,但是為了要做到關注點分離 (SoC 原則),所以在 View 和 Presenter 間都會加入一個介面 (ex: IView),然後以 IoC 的方式將 View 注射到 Presenter 中,而 Presenter 就使用介面所定義的方法去操控,而 View 就透過介面所定義的方法去呈現介面即可。但也因為受限於介面,所以 Presenter 只能依介面定義的動作去回應與處理,而不能再做更多的延伸功能,除非更改 View 的介面。
由上面各個架構的討論,我們可以得到以下的結果:
- MVC 架構適合於大型系統,它可以分層且可以在實體層面切割為不同的機器或服務,只要彼此間具有適當的通訊協定即可。
- MVVM 架構適合像 XAML 這種與程式碼無關 (code ignorance) 的使用者介面設計,只要 View 中下特定的指令與 ViewModel 串接,就可以享有 ViewModel 溝通的功能,而 ViewModel 只需做一些特別的介面實作,即可平順的和 View 溝通。
- MVP 架構適合集中由程式碼決定 View 動作的應用程式,而 View 只需要實作特定的介面即可,不需要太複雜的工作,但 Presenter 則可能會受限於 View 介面的動作,而無法做更進一步對 View 的控制。
最後我想提的是,MVC 的包容度比 MVVM 和 MVP 要來的高,在 MVC 的 V 層,可以再進一步的包含 MVVM 或 MVP 的實作,而 C 層也可以使用 MVP (V 是輸出的資料) 來進一步切割資料的流動與輸出,M 層則可以類似 MVVM 的架構,當 V (元件) 有資料的異動時,VM 即可自動偵測到並更新 Model (資料庫)。當然,要用什麼樣的架構去設計,端看當時的系統環境與需求來決定,而不是只想著要用同一種架構去做所有的系統。
Reference:
http://en.wikipedia.org/wiki/Model-view-presenter
http://en.wikipedia.org/wiki/Model-view-controller
http://en.wikipedia.org/wiki/Model_View_ViewModel
http://csharperimage.jeremylikness.com/2010/04/model-view-viewmodel-mvvm-explained.html
http://blog.vuscode.com/malovicn/archive/2007/12/18/model-view-presenter-mvp-vs-model-view-controller-mvc.aspx
http://msdn.microsoft.com/en-us/magazine/cc188690.aspx