MVP()
MVP是一種廣泛使用的UI架構模式適用於基於事件驅動的應用框架比如ASPNET Web Forms和Windows Forms應用MVP中的M和V分別對應於MVC的Model和View而P(Presenter)則自然代替了MVC中的Controller但是MVP並非僅僅體現在從Controller到Presenter的轉換更多地體現在ModelView和Presenter之間的交互上
MVC模式中元素之間混亂的交互主要體現在允許View和Model繞開Controller進行單獨交流這在MVP模式中得到了徹底解決如圖所示能夠與Model直接進行交互的僅限於PresenterView只能通過Presenter間接地調用ModelModel的獨立性在這裡得到了真正的體現它不僅僅與可視化元素的呈現(View)無關與UI處理邏輯(Presenter)也無關使用MVP的應用是用戶驅動的而非Model驅動的所以Model不需要主動通知View以提醒狀態發生了改變
圖 ModelViewPresenter之間的交互
MVP不僅僅避免了View和Model之間的耦合更進一步地降低了Presenter對View的依賴如圖所示Presenter依賴的是一個抽象化的View即View實現的接口IView這帶來的最直接的好處就是使定義在Presenter中的UI處理邏輯變得易於測試由於Presenter對View的依賴行為定義在接口IView中我們只需要Mock一個實現了該接口的View就能對Presenter進行測試
構成MVP三要素之間的交互體現在兩個方面即View/Presenter和Presenter/ModelPresenter和Model之間的交互很清晰僅僅體現在Presenter對Model的單向調用而View和Presenter之間該采用怎樣的交互方式是整個MVP的核心MVP針對關注點分離的初衷能否體現在具體的應用中很大程度上取決於兩者之間的交互方式是否正確按照View和Presenter之間的交互方式以及View本身的職責范圍Martin Folwer將MVP可分為PV(Passive View)和SC(Supervising Controller)兩種模式
PV與SC
解決View難以測試的最好的辦法就是讓它無需測試如果View不需要測試其先決條件就是讓它盡可能不涉及到UI處理邏輯這就是PV模式目的所在顧名思義PV(Passive View)是一個被動的View包含其中的針對UI元素(比如控件)的操作不是由View自身主動來控制而被動地交給Presenter來操控
如果我們純粹地采用PV模式來設計View意味著我們需要將View中的UI元素通過屬性的形式暴露出來具體來說當我們在為View定義接口的時候需要定義基於UI元素的屬性使Presenter可以對View進行細粒度操作但這並不意味著我們直接將View上的控件暴露出來舉個簡單的例子假設我們開發的HR系統中具有如圖所示的一個Web頁面我們通過它可以獲取某個部門的員工列表
圖 員工查詢頁面
現在通過ASPNET Web Forms應用來設計這個頁面我們來討論一下如果采用PV模式View的接口該如何定義對於Presenter來說View供它操作的控件有兩個一個是包含所有部門列表的DropDownList另一個則是顯示員工列表的GridView在頁面加載的時候Presenter將部門列表綁定在DropDownList上與此同時包含所有員工的列表被綁定到GridView當用戶選擇某個部門並點擊查詢按鈕後View將包含篩選部門在內的查詢請求轉發給Presenter後者篩選出相應的員工列表之後將其綁定到GridView
如果我們為該View定義一個接口IEmployeeSearchView我們不能按照所示的代碼將上述這兩個控件直接以屬性的形式暴露出來針對具體控件類型的數據綁定屬於View的內部細節(比如說針對部門列表的顯示我們可以選擇DropDownList也可以選擇ListBox)不能體現在表示用於抽象View的接口中另外理想情況下定義在Presenter中的UI處理邏輯應該是與具體的技術平台無關的如果在接口中涉及控件類型這無疑將Presenter也與具體的技術平台綁定在了一起
public interface IEmployeeSearchView
{
DropDownList Departments { get;}
GridView Employees { get; }
}
[] []
From:http://tw.wingwit.com/Article/program/net/201311/16129.html