導讀:概述MVC模式已經(jīng)出現了幾十年了,在GUI領(lǐng)域已經(jīng)得到了廣泛的應用,由于微軟ASP.NET MVC Framework的出現,致使MVC一度成為.NET社區的熱名話(huà)題。作為MVC的變種MVP模式,也已經(jīng)出現好幾年了,在微軟模式與實(shí)踐小組提供...
概述
MVC模式已經(jīng)出現了幾十年了,在GUI領(lǐng)域已經(jīng)得到了廣泛的應用,由于微軟ASP.NET MVC Framework的出現,致使MVC一度成為.NET社區的熱名話(huà)題。作為MVC的變種MVP模式,也已經(jīng)出現好幾年了,在微軟模式與實(shí)踐小組提供的Web Client Software Factory中,給出了實(shí)現MVP模式的應用程序最佳實(shí)踐,本文將試著(zhù)對這兩種實(shí)現比較一二。
MVC(Model-View-Controller,模型-視圖-控制器)模式是80年代Smalltalk-80出現的一種軟件設計模式,后來(lái)得到了廣泛的應用,其主要目的在于促進(jìn)應用中模型,視圖,控制器間的關(guān)注的清晰分離。MVP(Model-View-Presenter,模型-視圖-表示器)模式則是由IBM開(kāi)發(fā)出來(lái)的一個(gè)針對C++和Java的編程模型,大概出現于2000年,是MVC模式的一個(gè)變種,主要用來(lái)隔離UI、UI邏輯和業(yè)務(wù)邏輯、數據。在下面的文字中,如無(wú)特別說(shuō)明,MVC均指ASP.NET MVC Framework。
處理流程
對于處理流程方面兩者的區別,用下面這兩幅圖就可以說(shuō)明一切:
圖1:Model-View-Controller
圖2:Model-View-Presenter
處理流程方面,在MVC中,用戶(hù)的請求首先會(huì )到達Controller,由Controller從Model獲取數據,選擇合適的View,把處理結果呈現到View上;在MVP中,用戶(hù)的請求首先會(huì )到達View,View傳遞請求到特定的Presenter,Presenter從Model獲取數據后,再把處理結果通過(guò)接口傳遞到View。
View區別
ASP.NET MVC Framework中的View可以是一個(gè)ASP.NET頁(yè)面、用戶(hù)控件或者是母版頁(yè)。需要分別s繼承于ViewPage、ViewUserControl、ViewMasterPage。示例代碼:
public partial class Views_Blog_New : ViewPage{}
采用行內代碼進(jìn)行數據的呈現,當然也可以使用服務(wù)器控件,示例代碼:
<h2>ASP.NET MVC Framework Sample</h2><hr /><%=Html.ActionLink("Home", "Index")%> |<%=Html.ActionLink("New Post", "New")%><div><%foreach (Post post in ViewData){ %><div class="postitem"><strong>Title</strong>:<%=Html.Encode(post.Title) %></br><strong>Author</strong>:<%=Html.Encode(post.Author) %></br><strong>PubDate</strong>:<%=Html.Encode(post.PubDate.ToShortDateString()) %></br><strong>Content</strong>:<%=Html.Encode(post.Description) %></br><%=Html.ActionLink("Edit", new {action="Edit", Id=post.Id })%></div><br /><% } %></div>
在MVP中,仍然采用WebForm模型,其中View分為View接口和View實(shí)現兩部分,實(shí)現部分可以是ASP.NET頁(yè)面、用戶(hù)控件或者母版頁(yè):
public interface IProductDetail{string Name { set;}string Brand { set;}}public partial class Products_ProductDetail : Page, IProductDetail{}
使用服務(wù)器控件進(jìn)行呈現(也可以是HTML控件):
<asp:Content ID="content" ContentPlaceHolderID="DefaultContent" Runat="Server"><h1>ProductDetail</h1><p>名稱(chēng):<asp:Label ID="lbl_Name" runat="server" Text=""></asp:Label></p><p>品牌:<asp:Label ID="lbl_Brand" runat="server" Text=""></asp:Label></p></asp:Content>Controller和Presenter
ASP.NET MVC Framework中,一個(gè)View在整個(gè)應用程序中可以被多個(gè)Controller所調用。
public class PostController : Controller{[ControllerAction]public void New(){RenderView("New");}}public class BlogController : Controller{[ControllerAction]public void New(){RenderView("New");}}
MVP中一個(gè)View在整個(gè)應用程序中只對應一個(gè)特定的Presenter:
public partial class Products_ProductDetail : Page, IProductDetail{private ProductDetailPresenter _presenter;protected void Page_Load(object sender, EventArgs e){if (!this.IsPostBack){this._presenter.OnViewInitialized();}this._presenter.OnViewLoaded();}[CreateNew]public ProductDetailPresenter Presenter{set{this._presenter = value;this._presenter.View = this;}}}對開(kāi)發(fā)過(guò)程的影響
在A(yíng)SP.NET MVC Framework中,采用行內代碼進(jìn)行數據呈現,邏輯集中在Controller中,但是View無(wú)法完全交給UI設計人員完成。在MVP模式中,所有的業(yè)務(wù)邏輯交給Presenter去處理,這樣View中代碼就變得及其簡(jiǎn)潔,將可以輕易的把開(kāi)發(fā)人員和UI設計人員分開(kāi),如下圖所示:
對單元測試的支持
在單元測試方面的支持,ASP.NET MVC Framework在出現的時(shí)候就講促進(jìn)清晰的關(guān)注分離,可測試性和TDD。MVC Framewrok中的所以核心契約都是基于接口的,可以輕易地通過(guò)Mock來(lái)模擬??梢圆挥迷贏(yíng)SP.NET進(jìn)程中運行控制器,就能進(jìn)行單元測試。同時(shí)可以使用你想使用的任何單元測試框架來(lái)做單元測試,包括NUnit, MBUnit, MS Test等等。
MVP模式的出現,在一定程度上是為了便于UI的單元測試。由于所有的處理都放在了Presenter中,View中的代碼變得及其干凈簡(jiǎn)單,所以可以很方便的進(jìn)行單元測試,Web Client Software Factory中,提供了自動(dòng)化項目指導包,可以直接創(chuàng )建測試項目。
結束語(yǔ)
對于A(yíng)SP.NET MVC Framework和WCSF中的MVP模式之小小比較,到這里就結束了,不管是ASP.NET MVC Framework還是WCSF中的MVP模式,都是非常優(yōu)秀的模型,值得我們更進(jìn)一步去研究。