MVC和MVP到底有什么區別呢?


MVC和MVP到底有什么區別呢?

而MVP則是對MVC的進一步改造,以Andorid為例,實際上在MVC中很難區分Activity到底應該處於V還是C的角色,因為activity即包含了界面也包含了一部分邏輯處理。

MVP的出現就是為進一步分離業務邏輯和界面處理。在MVP中,M與V完全切斷聯系,由P進行總控。

當V接收到了操作,將相應的請求傳遞到P,由P進行業務處理以及與M進行交互,同時P又在恰當的時機對view進行更新(接口 / 回調方法 / 事件)

這樣V只需要暴露出接口,V與P通過接口通訊,一方面能夠將業務邏輯轉移至P,一方面通過接口使得P可以適配多個V。

 


 

從這幅圖可以看到,我們可以看到在MVC里,View是可以直接訪問Model的!從而,View里會包含Model信息,不可避免的還要包括一些業務邏輯。

在MVC模型里,更關注的Model的不變,而同時有多個對Model的不同顯示,及View。

所以,在MVC模型里,Model不依賴於View,但是View是依賴於Model的。不僅如此,因為有一些業務邏輯在View里實現了,導致要更改View也是比較困難的,至少那些業務邏輯是無法重用的。

Visual Studio等快速開發工具,讓我們很難把View和Controller分開,我們總是直接在View的事件響應函數里完成了Controller的代碼。而在ASP.NET和XAML里,使用了一種叫做Code-Behind的技術,可以把View和Controller進行分離。這樣,View就可以完全由UI設計工程師來完成,而Controller由程序員來完成,兩者可以直接合成不需要像現在一樣再由程序員做很多的工作。

把Controller和View混在一起,有什么問題?

1.難以測試。

  必須手動點擊,使用各種自動化的測試工具。

2.代碼難以重用。

  UI是很難重用,因為要求總是不同。所以,導致重復的代碼四處都是,維護麻煩。

MVP是如何解決MVC的問題的?

 

在MVP里,Presenter完全把Model和View進行了分離,主要的程序邏輯在 Presenter里實現。而且,Presenter與具體的View是沒有直接關聯的,而是通過定義好的接口進行交互,從而使得在變更View時候可以 保持Presenter的不變,即重用!

不僅如此,我們還可以編寫測試用的View,模擬用戶的各種操作,從而實現對Presenter的測試--而不需要使用自動化的測試工具。

我們甚至可以在Model和View都沒有完成時候,就可以通過編寫Mock Object(即實現了Model和View的接口,但沒有具體的內容的)來測試Presenter的邏輯。

在MVP里,應用程序的邏輯主要在Presenter來實現,其中的View是很薄的一層。 因此就有人提出了Presenter First的設計模式,就是根據User Story來首先設計和開發Presenter。在這個過程中,View是很簡單的,能夠把信息顯示清楚就可以了。在后面,根據需要再隨便更改View, 而對Presenter沒有任何的影響了。

如果要實現的UI比較復雜,而且相關的顯示邏輯還跟Model有關系,就可以在View和 Presenter之間放置一個Adapter。由這個 Adapter來訪問Model和View,避免兩者之間的關聯。而同時,因為Adapter實現了View的接口,從而可以保證與Presenter之 間接口的不變。這樣就可以保證View和Presenter之間接口的簡潔,又不失去UI的靈活性。

在MVP模式里,View只應該有簡單的Set/Get的方法,用戶用戶輸入和設置界面顯示的內容,除此就不應該有更多的內容,絕不容許直接直接訪問Model--這就是與MVC很大的不同之處。

參考:


MSDN的MVP介紹 
一個不錯的視頻演示 
Presenter First 
The Humble Dialog 
-----------------------------------------------

Alex在他的blog中對於mvc 與mvp 之間的比較:

【譯文】:


Model View Presenter vs Model View Controller
簡介

在我工作中經常需要處理一些由於開發人員沒能很清楚地理解MVC和MVP模式的區別的情況下使用它們而產生的問題。在這篇文章中我將會闡述一下我對兩者之間區別的一些理解。
在N層體系結構中MVC/P 模式僅僅只是用於表示層(presentation layer),理解這一點很重要。這兩個模式並不是關於怎么構建數據層(data layer)和服務層(service layer)的,而是關於怎么將數據(data)從用戶接口(view)中分離出來,以及用戶接口如何與數據進行交互的。這些模式的使用讓解除你的程序中表示層對對數據和控制邏輯的依賴,從而可以自由的變更表示層。


這兩種模式中三個部分的一般理解

1、模型(Model)表示數據模型和業務邏輯(business logic)。模型並不總是DataSet,DataTable之類的東西,它代表着一類組件(components)或類(class),這些組件或類 可以向外部提供數據,同時也能從外部獲取數據並將這些數據存儲在某個地方。簡單的理解,可以把模型想象成“外觀類(facade class)”。【譯注:這里的外觀是指“外觀模式”中所說的外觀。外觀的一般作用是為一個復雜的子系統提供高層次的簡單易用的訪問接口,可以參看下面的圖來理解它的原理:


2、視圖(View)將數據層現給用戶。一般的視圖都只是包含用戶界面(UI),而不包含界面邏輯。比如,Asp.net中包含控件的頁面(page)就是一個視圖。視圖可以從模型中讀取數據,但是不能修改或更新模型。
3、層現器(Presenter)/控制器(Controller)包含了根據用戶在視圖中的行為去更新模型的邏輯。視圖僅僅只是將用戶的行為告知控制器,而控制器負責從視圖中取得數據然后發送給模型。

MVC/P模式的核心是為了將模型從視圖/控制器中分離出來,從而使得模型獨立於它們,因此模型不包含對視圖和控制的引用。


什么是MVC(Model View Presenter)模式?

1、為了使得視圖接口可以與模型和控制器進行交互,控制器執行一些初始化事件
2、用戶通過視圖(用戶接口)執行一些操作
3、控制器處理用戶行為(可以用觀察着模式實現)並通知模型進行更新
4、模型引發一些事件,以便將改變發告知視圖
5、視圖處理模型變更的事件,然后顯示新的模型數據
6、用戶接口等待用戶的進一步操作

這一模式的有一下幾個要點:
1、視圖並不使用控制器去更新模型。控制器負責處理從視圖發送過來的用戶操作並通過與模型的交互進行數據的更新
2、 控制器可以和視圖融合在一塊。Visual Studion中對Windows Forms的默認處理方式就是這樣的。【譯注:比如我們雙擊一個Button,然后在它的事件里寫處理邏輯,然后將處理的數據寫回模型中。這里處理邏輯時 間應該是控制器的功能,但是我們並沒有專門寫一個控制器來做這件事情而是接受了VS的默認處理方式,將它寫在Form的代碼中,而這里的Form在MVC 中它就是一個View。所以這說vs默認的處理方式是將把控制器和視圖融合在一起的。】
3、控制器不包含對視圖的渲染邏輯(rendering logic)

“主動—MVC”模式,也是通常意義下的MVC模式

【譯 注:為什么說是主動的?View不是等Controller通知它Model更新了然后才從Model取數據並更新顯示,而是自己監視Model的更新 (如果用觀察者模式)或主動詢問Model是否更新。前面那種等待Controller通知的方式是下面所介紹的“被動—MVC”的實現方式。】

“被動—MVC”模式
與主動MVC的區別在於:
1、模型對視圖和控制器一無所知,它僅僅是被它們使用
2、控制器使用視圖,並通知它更新數據顯示
3、視圖僅僅是在控制器通知它去模型取數據的時候它才這么做(視圖並不會訂閱或監視模型的更新)
4、控制器負責處理模型數據的變化
5、控制器可以包含對視圖的渲染邏輯

MVP模式

與“被動—MVC模式”很接近,區別在於“視圖並不使用模型”。在MVP模式中視圖和模型是完全分離的,他們通過Presenter進行交互。
Presenter與控制器非常相似,但是它們也有一些的區別:
1、Presenter處理視圖發送過來的用戶操作(在MVC中視圖自己處理了這些操作)
2、它用更新過的數據去更新模型(在被動MVC中控制器只是通知視圖去更新過的模型中去取新的數據,而主動MVC中模型通知視圖去更新顯示,控制器不需要做工作)
3、檢查模型的更新(與被動MVC一樣)
4、(與MVC的主要區別)從模型中取數據然后將它們發送到視圖中
5、(與MVC的主要區別)將所做的更新告知視圖
6、(與MVC的區別)用Presenter渲染視圖

MVP的優勢

1、模型與視圖完全分離,我們可以修改視圖而不影響模型
2、可以更高效地使用模型,因為所以的交互都發生在一個地方——Presenter內部
3、我們可以將一個Presener用於多個視圖,而不需要改變Presenter的邏輯。這個特性非常的有用,因為視圖的變化總是比模型的變化頻繁。
4、如果我們把邏輯放在Presenter中,那么我們就可以脫離用戶接口來測試這些邏輯(單元測試)


MVP的問題

由於對視圖的渲染放在了Presenter中,所以視圖和Persenter的交互會過於頻繁。

還有一點你需要明白,如果Presenter過多地渲染了視圖,往往會使得它與特定的視圖的 聯系過於緊密。一旦視圖需要變更,那么 Presenter也需要變更了。比如說,原本用來呈現Html的Presenter現在也需要用於呈現Pdf了,那么視圖很有可能也需要變更。

MVP模式根據 Module,View,Presenter之間的交互,可以分為Passive View(常規MVP)和Supervising Controller 2種。

Passive View模式:

 

大 家會發現MVP與MVC最大的一個區別就是“Model與View層之間倒底該不該通信(甚至雙向通信)。我想這也是目前做這兩方面研究的專家所互相爭論 的戰場。必定各有各的好處和因好處要付出的代價。起碼在MVP模式下的Presenter要擁有“絕對權力”。如果沒有它,MODEL與View就是兩個 孤島,盡管各有各的地盤(完全解耦),但不會給企業帶來什么有用的價值。

所以我這里有一個比喻來形容MVP中的:
Presenter ----就是一個控制欲極強的女人,甚至就連“用什么姿勢”,它都要管一管。
當 然日里萬機操心多了就會讓自己要做的事越來越多,最終它面臨的就是該層代碼日益龐雜,且書寫起來不太方便,必定就連事件綁定這類雞毛算皮的事都要歸它管, 累不累呀。最終我們看到MVP中的View就真的代碼輕閑了不少(國企職工嘛),難怪說View只要從相應的[IVIEW]接口下實現相應的屬性和一些簡 單方法就完事了,而最終調用[IVIEW]接口下的那個視圖實例則完全交給了Presenter,這讓我想到了MVC中可以支持“自定義模版引擎(最終由 MVC框架來控制使用系統還是自定義的模版引擎)”以及平時大家常掛在嘴邊的換膚功能,想到這里多少還真有那么點意思了(精神層面上)。

當然在微軟內部對MVP的理解也有所不同,如下面中所說的Supervising Controller模式和之前大家看到的PassiveView.


Supervising Controller模式其實很接近於MVC的那張圖了,只是又提供了Presenter與View之間的“雙向通信”。這種做法也是有很多不同意見的,起碼對那些支持“單向依賴”的開發者而言是“嗤之以鼻”的。
說到這里,雖然PassiveView模式有些霸道,但必定是讓Model和View之間真正解耦,為開發者提供了最大的“控制成就感”,可以說想怎么控制視圖就怎么控制,但因此所造成的問題就是代碼書寫量和實現復雜性等問題了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM