從這幅圖能夠看到,咱們能夠看到在MVC裏,View是能夠直接訪問Model的!從而,View裏會包含Model信息,不可避免的還要包括一些業務邏輯。html
在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由程序員來完成,二者能夠直接合成不須要像如今同樣再由程序員作不少的工做。 mvc
把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很大的不一樣之處。
參考:
Alex在他的blog中對於mvc 與mvp 之間的比較:
【譯文】:
在我工做中常常須要處理一些因爲開發人員沒能很清楚地理解MVC和MVP模式的區別的狀況下使用它們而產生的問題。在這篇文章中我將會闡述一下我對二者之間區別的一些理解。
在N層體系結構中MVC/P 模式僅僅只是用於表示層(presentation layer),理解這一點很重要。這兩個模式並非關於怎麼構建數據層(data layer)和服務層(service layer)的,而是關於怎麼將數據(data)從用戶接口(view)中分離出來,以及用戶接口如何與數據進行交互的。這些模式的使用讓解除你的程序中表示層對對數據和控制邏輯的依賴,從而能夠自由的變動表示層。
一、模型(Model)表示數據模型和業務邏輯(business logic)。模型並不老是DataSet,DataTable之類的東西,它表明着一類組件(components)或類(class),這些組件或類 能夠向外部提供數據,同時也能從外部獲取數據並將這些數據存儲在某個地方。簡單的理解,能夠把模型想象成「外觀類(facade class)」。【譯註:這裏的外觀是指「外觀模式」中所說的外觀。外觀的通常做用是爲一個複雜的子系統提供高層次的簡單易用的訪問接口,能夠參看下面的圖來理解它的原理:
】
二、視圖(View)將數據層現給用戶。通常的視圖都只是包含用戶界面(UI),而不包含界面邏輯。好比,Asp.net中包含控件的頁面(page)就是一個視圖。視圖能夠從模型中讀取數據,可是不能修改或更新模型。
三、層現器(Presenter)/控制器(Controller)包含了根據用戶在視圖中的行爲去更新模型的邏輯。視圖僅僅只是將用戶的行爲告知控制器,而控制器負責從視圖中取得數據而後發送給模型。
MVC/P模式的核心是爲了將模型從視圖/控制器中分離出來,從而使得模型獨立於它們,所以模型不包含對視圖和控制的引用。
一、爲了使得視圖接口能夠與模型和控制器進行交互,控制器執行一些初始化事件
二、用戶經過視圖(用戶接口)執行一些操做
三、控制器處理用戶行爲(能夠用觀察着模式實現)並通知模型進行更新
四、模型引起一些事件,以便將改變發告知視圖
五、視圖處理模型變動的事件,而後顯示新的模型數據
六、用戶接口等待用戶的進一步操做
這一模式的有一下幾個要點:
一、視圖並不使用控制器去更新模型。控制器負責處理從視圖發送過來的用戶操做並經過與模型的交互進行數據的更新
二、 控制器能夠和視圖融合在一塊。Visual Studion中對Windows Forms的默認處理方式就是這樣的。【譯註:好比咱們雙擊一個Button,而後在它的事件裏寫處理邏輯,而後將處理的數據寫回模型中。這裏處理邏輯時 間應該是控制器的功能,可是咱們並無專門寫一個控制器來作這件事情而是接受了VS的默認處理方式,將它寫在Form的代碼中,而這裏的Form在MVC 中它就是一個View。因此這說vs默認的處理方式是將把控制器和視圖融合在一塊兒的。】
三、控制器不包含對視圖的渲染邏輯(rendering logic)
「主動—MVC」模式,也是一般意義下的MVC模式
【譯 注:爲何說是主動的?View不是等Controller通知它Model更新了而後才從Model取數據並更新顯示,而是本身監視Model的更新 (若是用觀察者模式)或主動詢問Model是否更新。前面那種等待Controller通知的方式是下面所介紹的「被動—MVC」的實現方式。】
「被動—MVC」模式
與主動MVC的區別在於:
一、模型對視圖和控制器一無所知,它僅僅是被它們使用
二、控制器使用視圖,並通知它更新數據顯示
三、視圖僅僅是在控制器通知它去模型取數據的時候它才這麼作(視圖並不會訂閱或監視模型的更新)
四、控制器負責處理模型數據的變化
五、控制器能夠包含對視圖的渲染邏輯
MVP模式
與「被動—MVC模式」很接近,區別在於「視圖並不使用模型」。在MVP模式中視圖和模型是徹底分離的,他們經過Presenter進行交互。一、模型與視圖徹底分離,咱們能夠修改視圖而不影響模型
二、能夠更高效地使用模型,由於因此的交互都發生在一個地方——Presenter內部
三、咱們能夠將一個Presener用於多個視圖,而不須要改變Presenter的邏輯。這個特性很是的有用,由於視圖的變化老是比模型的變化頻繁。
四、若是咱們把邏輯放在Presenter中,那麼咱們就能夠脫離用戶接口來測試這些邏輯(單元測試)
因爲對視圖的渲染放在了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中的: