[Architecture] MVP, MVC, MVVM, 傻傻分不清楚~

最近 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 的介面。

image

Source: http://blog.vuscode.com/malovicn/archive/2007/12/18/model-view-presenter-mvp-vs-model-view-controller-mvc.aspx

由上面各個架構的討論,我們可以得到以下的結果:

  1. MVC 架構適合於大型系統,它可以分層且可以在實體層面切割為不同的機器或服務,只要彼此間具有適當的通訊協定即可。
  2. MVVM 架構適合像 XAML 這種與程式碼無關 (code ignorance) 的使用者介面設計,只要 View 中下特定的指令與 ViewModel 串接,就可以享有 ViewModel 溝通的功能,而 ViewModel 只需做一些特別的介面實作,即可平順的和 View 溝通。
  3. 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