ASP.NET MVC 模式

ASP.NET MVC 是一個全新的Web應(yīng)用框架

  • ASP.NET 代表支撐應(yīng)用框架的技術(shù)平臺,表明ASP.NET MVC和傳統(tǒng)的WebForm應(yīng)用框架一樣,都是建立在ASP.NET平臺之上。
  • MVC 表示該框架背后的設(shè)計思想,意味著ASP.NET MVC采用了MVC架構(gòu)模式。

MVC在20世紀70年代后期出現(xiàn),產(chǎn)生于Xerox PARC施樂公司的帕洛阿爾托研究中心的Smalltalk項目,當時將其構(gòu)想為早期GUI應(yīng)用程序的一種組織方式。最初的MVC模型的某些細節(jié)依賴于Smalltalk特有的概念,如屏幕和工具等,但更廣泛的概念仍然適用于現(xiàn)在的應(yīng)用程序,特別適用于Web應(yīng)用程序。

與MVC應(yīng)用程序的交互遵循著用戶動作和視圖更新的自然周期,在此周期中,假設(shè)視圖是無狀態(tài)的,這與支撐Web應(yīng)用程序的HTTP請求和響應(yīng)方式非常吻合。

進一步地,MVC強制關(guān)注分離(Separation of Concerns) - 域模型與控制器邏輯與UI用戶界面是松耦合關(guān)系。在一個Web應(yīng)用程序中,這意味著凌亂的HTML與應(yīng)用程序的其他部分是分離開來的,從而使維護與測試更加簡單容易。這導致Ruby on Rails稱為復興的MVC主流,并使其稱為MVC模型的實現(xiàn)模板。自MVC出現(xiàn)并顯現(xiàn)出優(yōu)勢后,許多其他MVC框架也相繼出現(xiàn)。

從高級術(shù)語上說,MVC模式意味著一個MVC應(yīng)用程序?qū)⒈环蛛x成至少3個部分。

  • 模型(Model)
    含有或表現(xiàn)用戶進行操作的數(shù)據(jù),模型可以是簡單的視圖模型(ViewModel),它們只表現(xiàn)視圖與控制器之間傳遞的數(shù)據(jù),也可以是域模型(Domain Model),它包含業(yè)務(wù)領(lǐng)域的數(shù)據(jù),以及處理這些數(shù)據(jù)的操作、轉(zhuǎn)換、規(guī)則。
    模型是對應(yīng)用程序工作的定義,負責保持數(shù)據(jù)的整體狀態(tài)和一致性。模型也由不是其職責的內(nèi)容來定義:模型不涉及UI渲染或請求處理,那些是視圖和控制器的職責。視圖含有將模型元素顯示給用戶的邏輯,見此而已。它們不直接感知模型,也不以任何方式與模型直接通信??刂破魇且晥D與模型之間的橋梁,請求來自客戶端,并由控制器對其進行服務(wù),而今選擇一個相應(yīng)的視圖向用戶進行顯示,并在必要時執(zhí)行模型上的相應(yīng)操作。
    MVC應(yīng)用程序最重要的部分是域模型,對于應(yīng)用程序必須支持的業(yè)務(wù)或活動中存在的現(xiàn)實實體、操作、規(guī)則等,可以通過對它們進行標識的方法建立模型,這種模型被稱為域(Domain)。
    為了實現(xiàn)ASP.NET MVC框架這一目的,域模型往往是一組C#類型(類、結(jié)構(gòu)等),統(tǒng)稱為域類型(Domain Type)。域中的操作類型中定義的方法來實現(xiàn)。而域規(guī)則表示成這些方法中的邏輯?;蛘咄ㄟ^運用C#的注解屬性來實現(xiàn)。當創(chuàng)建一個域類型來表現(xiàn)特定的數(shù)據(jù)片段時,便創(chuàng)建了一個域?qū)ο螅―omainObject)。域模型通常是持久化的,且一直處于活動狀態(tài),其實現(xiàn)由許多不同方式,但關(guān)系型數(shù)據(jù)庫時最通常的選擇。
    簡言之,域模型是應(yīng)用程序中有無數(shù)據(jù)及其處理的唯一和權(quán)威的定義,一個持久化的域模型也是域所表現(xiàn)的狀態(tài)的權(quán)威定義。
    域模型方法解決了應(yīng)用程序維護中出現(xiàn)的許多問題,如操縱模型中數(shù)據(jù)、添加新的過程或規(guī)則、域模型是應(yīng)用程序必須修改的唯一地方。
  • 視圖(View)
    用于將模型的某些部分渲染成用戶界面
  • 控制器(Controller)
    處理傳入的請求,執(zhí)行模型上的操作,并選擇渲染給用戶的視圖。

MVC架構(gòu)的每個部分都是定義良好和自包含的,這稱為關(guān)注分離。模型中操作數(shù)據(jù)的邏輯僅包含在模型中,顯示數(shù)據(jù)的邏輯僅包含著在視圖中,處理用于請求和用戶輸入的代碼僅包含在控制器中。利用各部分之間清晰的分離,無論應(yīng)用程序有多大,在其整個生命周期中都會更易于維護和擴充。

傳統(tǒng)MVC模式

對于面向最終用戶的應(yīng)用來說,需要具有一個與用戶進行交互的可視化UI界面,又稱為視圖(View)。

在早期傾向于將所有與UI相關(guān)的操作糅合在一起,這些操作包括UI界面呈現(xiàn)、用戶交互操作的捕獲與響應(yīng)、業(yè)務(wù)流程的執(zhí)行、對數(shù)據(jù)的存取等。這種設(shè)計模式被稱為自治視圖(Autonomous View,AV)。

自治視圖

典型的人機交互應(yīng)用具有3個主要的關(guān)注點:數(shù)據(jù)在可視化界面上的呈現(xiàn)、UI處理邏輯(用于處理用戶交互式操作的邏輯)、業(yè)務(wù)邏輯。自治視圖模式將三者混合在一起,勢必帶來問題。

  • 重用性

業(yè)務(wù)邏輯是與UI無關(guān)的,應(yīng)該最大限度地被重用。將業(yè)務(wù)邏輯定義在自治視圖中,相當于將它完全與視圖本身綁定在一起。若將UI的行為抽象出來,基于抽象化UI的處理邏輯也是可以被共享的,但是定義在自治視圖中的UI處理邏輯也完全喪失了重用的可能。

  • 穩(wěn)定性

業(yè)務(wù)邏輯具有最強的穩(wěn)定性,UI處理邏輯次之,可視化界面上的呈現(xiàn)最差。將不同穩(wěn)定性的元素混合一體,具有最差穩(wěn)定性的元素決定了整體的穩(wěn)定性,這是“短板理論”在軟件設(shè)中的體現(xiàn)。

  • 可測試性

任何涉及UI的組件都不易測試,因為UI是呈現(xiàn)給人看的,并且會與人進行交互,用機器來模擬對組件實施自動化測試本身就不是一件容易的事。

為了解決自治視圖導致的問題,采用“關(guān)注點分離”(Seperation of Concerns, SoC)的原則將可視化界面呈現(xiàn)、UI處理邏輯、業(yè)務(wù)邏輯三者分離,并采用合理的交互方式將他們之間的依賴降到最低,即MVC。

MVC 范例

MVC的創(chuàng)建者挪威計算機專家,奧斯陸大學名譽教授 Trygve M. H. Reenskau。MVC是他在1979年訪問施樂帕克研究中心(Xerox Palo Alto Research Center, Xerox PARC)期間提出的一種針對GUI應(yīng)用的軟件架構(gòu)模式。

MVC體現(xiàn)了“關(guān)注點分離”設(shè)計方針,將人機交互引用設(shè)計的功能分為Model、Controller、View三部分,各司其職。

  • Model

Model是對應(yīng)用狀態(tài)和義務(wù)功能的封裝,可理解為同時包含數(shù)據(jù)和行為的領(lǐng)域模型(Domain Model)。

Model接受Controller的請求并完成相應(yīng)的義務(wù)處理,在應(yīng)用狀態(tài)改變時向View發(fā)出相應(yīng)的通知。

  • View

View實現(xiàn)可視化界面的呈現(xiàn)并捕獲最終用戶的交互操作,View捕獲到的用戶交互操作后會直接轉(zhuǎn)發(fā)給Controller,后者完成相應(yīng)的UI邏輯。如果需要涉及業(yè)務(wù)功能的調(diào)用,Controller會直接調(diào)用Model。在完成UI處理之后,Controller會根據(jù)需要控制原View或創(chuàng)建新的View對用戶交互操作予以響應(yīng)。

MVC之間的交互

傳統(tǒng)的MVC很多人會認為Controller僅僅是View和Model之間的中介,實則不然,View和Model之間存在直接聯(lián)系,View不僅可以直接調(diào)用Model查詢其狀態(tài)信息,當Model的狀態(tài)發(fā)生改變的時候,也可以直接通知View。例如股價實時價位的應(yīng)用中維護股價的信息的Model,在股價變化的情況下可直接通知相關(guān)的View改變其顯示狀態(tài)。

從消息交互模式的角度來講,無論是Model在應(yīng)用狀態(tài)發(fā)生改變時通知View,還是View在捕獲到用戶交互操作后通知Controller,消息都是以“單向(One-Way)”方式流動的,推薦采用事件機制來實現(xiàn)兩種類型過的通知。

從設(shè)計角度來講,采用觀察者模式(Observer)通過注冊/訂閱的方式來實現(xiàn),具體來講就是讓View作為Model的觀察者,通過注冊相應(yīng)的事件來檢測狀態(tài)的改變。讓Controller作為View的觀察者,通過注冊相應(yīng)的事件來處理用戶的交互操作。

MVC和所謂的“三層架構(gòu)”兩者沒有什么可比性,MVC更不是分別對應(yīng)UI、業(yè)務(wù)邏輯、數(shù)據(jù)存取三個層次。Trygve M. H. Reenskau提出MVC是將其作為構(gòu)建整個GUI應(yīng)用的架構(gòu)模式,它更多地體現(xiàn)為一個領(lǐng)域模型。對于多層架構(gòu)來說,MVC是被當成UI呈現(xiàn)層(Presentation Layer)的設(shè)計模式,Model則更多體現(xiàn)為訪問業(yè)務(wù)層的入口(Gateway)。

MVC 變體

采用MVC范例將可視化UI元素的呈現(xiàn)、UI處理邏輯、業(yè)務(wù)邏輯分別定義在View、Controller、Model中。MVC并沒有對三者之間的交互進行嚴格的限制,主要體現(xiàn)在它允許View和Model繞開Controller進行直接交互,不僅View可以通過調(diào)用Model獲取需要呈現(xiàn)給用戶的數(shù)據(jù)。Model也可以直接通知View讓其感知到應(yīng)用狀態(tài)的變化。將MVC范例應(yīng)用于具體的項目開發(fā)時,不論是基于GUI的桌面應(yīng)用或是基于瀏覽器的Web應(yīng)用,如果不多MVC之間的交互作更為嚴格的約束,編寫的程序可能比自治視圖更加難以維護。

現(xiàn)在MVC被視為一種模式(Pattern),而最初的提出者卻將其視為一種范例(Paradigm)。模式和范例的區(qū)別在于,模式可以直接在具體的應(yīng)用上使用,范例僅僅提供基本指導方針。

軟件設(shè)計的發(fā)展歷程中出現(xiàn)了MVC的變體(Variation),它們遵守定義在MVC中的基本原則,但對于三者之間的交互制定了更為嚴格的規(guī)范。

MVP

“模型-視圖-呈現(xiàn)器(Model-View-Presenter, MVP)”是MVC的一種變異,以便更容易地適應(yīng)狀態(tài)化的GUI平臺,如Windows Form或ASP.NET Web Form。

MVP模式中,呈現(xiàn)器P具有與MVC控制器同樣的職責,但它與狀態(tài)化視圖有更直接的關(guān)系,根據(jù)用戶的輸入和動作,直接管理著UI組件中顯示的數(shù)據(jù)。

該模式有以下兩種實現(xiàn):

  • 被動式視圖(Passive View)實現(xiàn):此種實現(xiàn)中,視圖不包含邏輯,是UI控件的容器,由呈現(xiàn)器直接進行操縱。
  • 監(jiān)管控制器(Supervising Controller)實現(xiàn):此種實現(xiàn)中,視圖可能要負責一些具有表現(xiàn)邏輯的元素,如數(shù)據(jù)綁定,并給出對域模型數(shù)據(jù)源的引用。

這兩種實現(xiàn)之間的差別涉及視圖如何智能化,任何一種方式,呈現(xiàn)器與GUI框架都解耦的,這使得呈現(xiàn)器邏輯簡單且易于單元測試。

MVP是一種廣泛使用的UI架構(gòu)模式,適用于基于事件驅(qū)動的應(yīng)用框架,比如ASP.NET Web Forms和Windows Forms應(yīng)用。

MVP中的M和V分別對應(yīng)于MVC的Model和View,而P(Presenter)則自然代替了MVC中的Controller。MVP并非僅僅體現(xiàn)在從Controller到Presenter的轉(zhuǎn)換,更多地體現(xiàn)在Model、View、Presenter之間的交互上。

MVC范例中三元素之間混亂的交互主要體現(xiàn)在允許View和Model繞開Controller進行單獨交流,這個問題在MVP中得到了徹底解決。

MVP三者交互

能夠與Model直接進行交互的僅限于Presenter,View只能通過Presenter間接地調(diào)用Model。Model的獨立性在這里得到了真正的體現(xiàn),它不僅僅與可視化元素的呈現(xiàn)(View)無關(guān),與UI處理邏輯(Presenter)也無關(guān)。使用MVP的應(yīng)用是用戶驅(qū)動而非Model驅(qū)動的,所以Model無需主動通知View以提醒狀態(tài)發(fā)生了改變。

MVP不僅避免了View和Model之間的深度耦合,更進一步降低了Presenter對View的依賴。Presenter依賴的是一個抽象化的View,即具體View實現(xiàn)的接口IView,這帶來的最直接的好處就是使定義在Presenter中的UI處理邏輯變得更易于測試。由于Presenter對View的依賴行為定義在接口IView中,僅需Mock一個實現(xiàn)了該接口的View就能對Presenter進行測試。

MVP三要素的交互主要體現(xiàn)在:View與Presenter、Presenter與Model之間的交互。Presenter和Model之間的交互很清晰,僅僅體現(xiàn)為Presenter對Model的單向調(diào)用。View和Presenter之間采用怎樣的交互式整個MVP的核心。MVP針對關(guān)注點分離的初衷能否體現(xiàn)在具體的應(yīng)用中,很大程序上取決于兩者之間的交互方式是否正確。

按照View和Presenter之間的交互方式,以及View本身的職責范圍,Martin Folwer將MVP分為PV(Passive View)和SC(Supervising Controller)兩種模式。

MVVM

“模型-視圖-視圖模型(MVVM, Model-View-View Model)”模式是MVC的最新變異,源于微軟并被應(yīng)用于WPF。在MVVM模型中,模型和視圖具有與MVC同樣的作用。所不同的是MVVM中關(guān)于視圖模型的概念,是用戶界面的一種抽象表示 -- 典型地是一個C#類,它即暴露了視圖中待顯示數(shù)據(jù)的模型屬性,也暴露了能夠通過UI進行調(diào)用的對數(shù)據(jù)的操作。與MVC的控制器不同,MVVM視圖模型沒有視圖或任何特定UI技術(shù)的觀念。MVVM視圖使用WPF的綁定(Binding)特性,將視圖控件所暴露的屬性與視圖模型所暴露的屬性雙向地關(guān)聯(lián)在一起。

Model2

MVC最初作為桌面應(yīng)用的架構(gòu)模式并不太適合Web,Web應(yīng)用于桌面應(yīng)用的主要區(qū)別在于用戶是通過瀏覽器與應(yīng)用進行交互,交互請求和響應(yīng)是通過HTTP請求和響應(yīng)來完成的。

為了讓MVC能夠為Web應(yīng)用提供原生的支持,Java陣營提出了Model2的Web架構(gòu)模式。JavaWeb具有兩種基于MVC的架構(gòu)模式,分別稱之為Model1和Model2,Model1類似自治視圖模式。

為了讓開發(fā)者采用相同的編程模式進行桌面應(yīng)用和Web應(yīng)用開發(fā),微軟通過ViewState和Postback對HTTP請求和響應(yīng)機制進行了封裝,能夠像編寫WindowsForms應(yīng)用一樣采用事件驅(qū)動的方式進行ASP.NET Web Forms應(yīng)用的編程。Models則采用完全不同的設(shè)計,讓開發(fā)者直接面向WEB,關(guān)注HTTP的請求和響應(yīng),所以Model2提供對Web引用原生的支持。

對于Web應(yīng)用來說,和用戶直接交互的UI界面由瀏覽器來呈現(xiàn),用戶交互請求通過瀏覽器以HTTP請求的方式發(fā)送到Web服務(wù)器,服務(wù)器對請求進行相應(yīng)的處理并最終返回一個HTTP回復對請求予以響應(yīng)。

Model2中一個HTTP請求的目標是Controller中某個Action,具體體現(xiàn)為定義在Controller類型的某個方法,所以對請求的處理最終體現(xiàn)在對目標Controller對象的激活和對目標Action方法的執(zhí)行。一把來說,Controller的類型和Action方法的名稱及作為Action方法的部分參數(shù)可直接通過請求的URL解析出來。

Model2的交互流程

通過攔截器(Interceptor)對抵達Web服務(wù)器的HTTP請求進行攔截,Web應(yīng)用框架都提供了這樣的攔截機制。對于ASP.NET來說,通過HttpModule的形式來定義這樣的攔截器。攔截器根據(jù)當前請求解析出目標Controller的類型和對應(yīng)的Action方法的名稱,隨后目標Controller被激活,相應(yīng)的Action方法被執(zhí)行。

目標Action方法被執(zhí)行過程中,可調(diào)用Model獲取相應(yīng)的數(shù)據(jù)或改變其狀態(tài)。在Action方法執(zhí)行的最后階段一般會創(chuàng)建一個View,后者最終被轉(zhuǎn)換成HTML以HTTP響應(yīng)的形式返回到客戶端并呈現(xiàn)在瀏覽器中,綁定在View上的數(shù)據(jù)來源于Model或基于顯示要求進行簡單邏輯計算,有時將其稱為VM(View Model),即基于View的Model。

ASP.NET MVC 與 Model2

ASP.NET MVC是根據(jù)Model2模式設(shè)計的,對HTTP請求進行攔截以實現(xiàn)對目標Controller和Action名稱的解析式通過一個自定義HttpModule來實現(xiàn)的,目標Controller的激活和Action方法的執(zhí)行是通過一個自定義HttpHandler來完成的。

MVC的Model主要體現(xiàn)為維持應(yīng)用狀態(tài)并提供業(yè)務(wù)功能的領(lǐng)域模型,或者是多層架構(gòu)中進入業(yè)務(wù)層的入口合伙業(yè)務(wù)服務(wù)的代理,但是ASP.NET MVC中的Model還是這個Model嗎?ASP.NET MVC的Model僅僅是綁定到View上的數(shù)據(jù)而已,和MVC中的Model并不是一回事兒。由于ASP.NET MVC中的Model是服務(wù)于View的,可見其成為ViewModel。

由于ASP.NET MVC只是View Model,所以ASP.NET MVC應(yīng)用框架本身僅僅關(guān)注View和Controller,真正的Model以及Model和Controller直接的交互體現(xiàn)在如何來設(shè)計Controller。

MVC的ASP.NET實現(xiàn)

在MVC中,控制器是C#類,派生自System.Web.Mvc.Controller類。從這個Controller派生而來的類中,每個public方法都稱為一個動作方法(Action Method),這種動作方法通過ASP.NET的路由系統(tǒng)與一個可配置的URL相關(guān)聯(lián)。當一個請求被發(fā)送給一個動作方法相關(guān)聯(lián)的URL時,便會執(zhí)行控制器中的語句,以進行域模型上的一些操作,然后選擇一個視圖顯示給客戶端。

MVC應(yīng)用程序中的交互

ASP.NET MVC框架使用視圖引擎(ViewEngine), 該引擎是負責處理視圖的組件,以便為瀏覽器生成響應(yīng)。MVC的早期版本使用標準的ASP.NET視圖引擎,使用改進的WebForm標記語法來處理ASPX頁面。

MVC與其他模式比較

  1. 智能UI模式
    智能用戶界面(Smart User Interface, Smart UI,智能UI)如Windows Form或ASP.NET Web Form。為建立智能UI應(yīng)用程序,開發(fā)者需構(gòu)建一個用戶界面,通常是將一組組件(Component)或控件(Control)拖放到設(shè)計界面或畫布上??丶ㄟ^對單擊按鈕、按鈕、鼠標移動等發(fā)送事件的報告來與用戶進行交互。開發(fā)者將代碼添加到一系列事件處理程序(Event Handler)中,以便對事件作出響應(yīng)。
智能UI模式

智能UI最大的缺點是難以維護和擴展,域模型與帶有用戶界面代碼的業(yè)務(wù)邏輯混搭在一起,導致了重復。在MVC中,智能UI被認為是一種抵抗模式(Anti-pattern),是不屑一切代價應(yīng)該避免的。

2.模式-視圖架構(gòu)

模型-視圖(Model-View)架構(gòu)提供了一種改進智能UI的方法,將事務(wù)邏輯才抽取形成能獨立的域模型。數(shù)據(jù)、過程、規(guī)則被自己集中在應(yīng)用程序的部件中。不過帶來的問題是:UI與域模型結(jié)合得十分緊密,對每部分的單元測試都和困難,其次問題來自于實際情況而非模式的定義。模型含有大量數(shù)據(jù)訪問代碼,這意味著,數(shù)據(jù)模型并不僅僅只包含事務(wù)數(shù)據(jù)、操作和規(guī)則。

模型-視圖架構(gòu)
  1. MVC
    三級(Three-tier)或三層(Three-Layer)模式將持久化代碼從域模型中分離出來,并將其放入一個叫做“數(shù)據(jù)訪問層(DAL, Data Access Layer)”的新組件中。
MVC

三層架構(gòu)是事務(wù)性應(yīng)用能程序使用最廣泛的模式,對如何實現(xiàn)UI沒有約束,并提供了較好的關(guān)注分離且又不太復雜。某些情況下DAL能夠使單元測試相對容易。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 這是大自然的杰作,這也是有心人的情懷。這是春天里的守望,這也是綠葉對根的一片情意! —— 趙老師
    尛草兒閱讀 313評論 0 0
  • 1 畢業(yè)時,我想了解這個社會這個世界?,F(xiàn)在2016年12月5日,我發(fā)現(xiàn)我依然不了解這個世界,現(xiàn)在我只想躲在自己的世...
    飛魚kiwi閱讀 290評論 0 0
  • 媽媽用手機玩微信有些日子了,這是先前想也不敢想的事情,現(xiàn)在媽媽玩得很不錯,經(jīng)常主動給我們幾個發(fā)信息,搶紅包.......
    洛葉123閱讀 100評論 0 0
  • 有誰許我的承諾 一字一句堆砌成王國 我在城里 誦念一世的佛 回轉(zhuǎn)夢空 有誰能續(xù)寫我這美好的經(jīng)過 可又有誰 能免去終...
    顧北枝閱讀 421評論 0 0

友情鏈接更多精彩內(nèi)容