標籤:組合 ble ber manage 擴充性 代碼產生 lte set j2ee
【轉載】MVC架構在Asp.net中的應用和實現
轉載自:http://www.cnblogs.com/baiye7223725/archive/2007/06/07/775390.aspx
摘要:本文主要論述了MVC架構的原理、優缺點以及MVC所能為Web應用帶來的好處。並以“成都市資訊化資產管理系統”架構設計為例,詳細介紹其在Asp.net環境下的具體實現。旨在協助Web設計開發人員更好的瞭解和掌握MVC,合理利用MVC構建優秀的Web應用。
關鍵字:MVC、視圖、控制器、模型、Asp.net
Application and Implementation of MVC Construction in Asp.net
Abstract: This article mainly elaborated the construction principle of MVC, the merits and shortcoming as well as MVC can be an advantage, which the Web application brings. And take “the Chengdu informationization property management system management system” the frame design as the example, introduces its concrete realization in detail under Asp. net environment. Is for the purpose of helping Web to design an exploiter better understanding and to grasp MVC, reasonably constructs the outstanding Web application using MVC.
Keywords: MVC 、View 、Controller、Model、Asp.net
0 引言
許多Web應用都是從資料存放區檢索資料並將其顯示給使用者。在使用者更改資料之後,系統再將更新內容儲存到資料存放區中。因為關鍵的資訊流發生在資料存放區和使用者介面之間,所以很多應用將資料和使用者介面這兩部分綁在一起,以減少編碼量並提高應用程式效能。但是,這種看起來自然而然的方法有一些大問題。一是,使用者介面的更改往往比資料存放區系統的更改頻繁得多。二是,這種耦合往往會並其他商務邏輯。那麼如何讓 Web 應用程式的使用者介面功能實現模組化,以便可以輕鬆地單獨修改各個部分呢?物件導向的設計模式是經驗的總結,MVC架構可以很好地解決上述問題。
.NET是當今設計和開發各種Web應用的主流平台,MVC架構在J2EE平台上已有成熟的設計方案,而在.NET平台上卻少有應用。所以討論其在Asp.net環境下的應用和實現,仍很有意義。
本文首先論述了MVC架構的原理、優缺點以及它所能為Web應用帶來的好處。並結合作者在“成都微軟技術中心”實習期間,研發項目的經驗。介紹了一種在Asp.net環境下的實現方式。旨在協助Web設計開發人員更好的瞭解和掌握MVC,合理利用MVC構建優秀的Web應用。雖然本文是在.net環境下的實現,但這並不妨礙你對MVC架構的理解。學習MVC架構,重在學習其思想。
1 MVC介紹
MVC是一種軟體開發架構,它包含了很多的設計模式[1],最為密切是以下三種:Observer (觀察者模式), Composite(組合模式)和Strategy(策略模式)。MVC最初是在Smalltalk-80中被用來構建使用者介面的[2]。
MVC架構把資料處理,程式輸入輸出控制及資料顯示分離開來,並且描述了不同組件的對象間的通訊方式。使得軟體可維護性,可擴充性,靈活性以及封裝性大大提高;MVC(Model-View-Controller)把系統的組成分解為M(模型)、V(視圖)、C(控制器)三種組件。視圖表示資料在螢幕上的顯示。控制器提供處理過程式控制制,它在模型和視圖之間起串連作用。控制器本身不輸出任何資訊和做任何處理,它只負責把使用者的請求轉成針對Model的操作,和調用相應的視圖來顯示Model處理後的資料。三者之間關係如2.1:
圖2.1 MVC關係圖
2、為什麼要在Web應用中使用MVC架構
使用者介面邏輯的更改往往比商務邏輯頻繁,尤其是在基於Web的應用程式中。例如,可能添加新的使用者介面頁,或者可能完全打亂現有的頁面配置。對顯示的更改,儘可能地不要影響到資料和商務邏輯。
目前大部分Web應用都是將資料代碼和表示混在一起。經驗比較豐富的開發人員會將資料從展示層分離開來,但這通常不是很容易做到的,它需要精心的計劃和不斷的嘗試。MVC從根本上強制性的將它們分開。儘管構造MVC應用需要一些額外的工作,但它帶來的好處是無庸質疑的。
2.1 提高代碼重用率
最重要的一點是多個視圖能共用一個模型,無論使用者想要Flash介面或是 WAP 介面;用一個模型就能處理它們。由於已經將資料和商務規則從展示層分開,所以可以最大化的重用代碼。
2.2 提高程式的可維護性
因為模型是自包含的,並且與控制器和視圖相分離,所以很容易改變資料層和商務規則[3]。例如,把資料庫從MySQL移植到Oracle,或者把基於RDBMS資料來源改變到LDAP,只需改變模型即可。一旦正確的實現了模型,不管資料來自哪裡,視圖都會正確的顯示它們。MVC架構的運用,使得程式的三個組件相互對立,大大提高了程式的可維護性。
2.3 有利於團隊開發
在開發過程中,可以更好的分工,更好的協作。有利於開發出高品質的軟體。良好的項目架構設計,將減少編碼工作量 :採用MVC結構 + 代碼產生器,是大多數Web應用的理想選擇。部分模型(Model)、和預存程序一般可用工具自動產生。控制(Controller)器比較穩定,一般由於架構師(也可能是有經驗的人)完成;那麼整個項目需要手動編寫代碼的地方就只有視圖(View)了。在這種模式下,個人能力不在特別重要,只要懂點文法基礎的人都可以編寫,無論項目成員寫出什麼樣的代碼,都在專案管理者的可控範圍內。即使項目中途換人,也不會有太大問題。在個人能力參差不齊的團隊開發中,採用MVC開發是非常理想的。
3 MVC在 Asp.net中的原理及實現
| Asp.net提供了很好實現這種模式的類似環境。通過在ASPX頁面中開發使用者組件或繼承母板頁MasterPage來實現視圖;控制器的功能一般可以放在對應的邏輯功能代碼(.cs)中實現;模型通常對應應用系統的業務部分。模型一般包含商務邏輯、商務規則和資料訪問層。MVC可和經典的N層結構配合使用。將使用者顯示(視圖)從動作(控制器)中分離出來,提高了代碼的重用性。將資料(模型)從對其操作的動作(控制 器)分離出來可以設計一個與後台儲存資料無關的系統。就MVC結構的本質而言,它是一種解決耦合系統問題的方法[4]。實現基於MVC的應用需要完成以下步驟,如右圖3.1所示: |
|
1、分析當前應用,分解系統功能:
分析當前應用問題,分離出系統的核心功能(Model)、系統的輸入輸出(View)、系統的輸流程式控制制,行為控制等控制功能(Controller)三大部分。
2、設計和實現模型:
設計模型組件使其封裝應用功能、屬性。提供訪問顯示資料的操作,提供控制內部行為的操作以及其他必要的操作介面。這部分的構成與具體的應用問題緊密相關。
3、設計和實現視圖:
設計每個視圖的顯示形式,視圖從模型中擷取資料,並將資料顯示在螢幕上。提供發送使用者請求給控制器;提供允許控制器選擇視圖。
4、設計和實現控制器:
對於每個視圖,實現對使用者的請求映射到模型。並根據模型處理結果,選擇合適的視圖顯示。在模型狀態的影響下,控制器使用特定的方法接受和解釋這些事件。控制器的初始化建立起與模型和視圖的聯絡,(這裡一般會用觀察者模式)並且啟動事件處理機制。事件處理機制的具體實現方法依賴於介面的工作平台。
MVC並沒有明確的定義,它僅代表一種軟體設計思想。所以在不同的應用環境下,可能有不同的實現方式。只有深刻理解其思想,結合實際情況。才能構建合理的應用。下面以“成都市資訊化資產管理系統”架構設計為例,介紹MVC構架在Asp.net下的一種實現方式。該架構中並沒有使用觀察者模式,因為依賴關係(本項目中只有兩種視圖,列表頁面和編輯、查看詳情頁面。而且將來增加視圖的可能性也不大)固定或者幾乎固定時,加入一個觀察者模式,只會增加系統複雜性。
本項目架構結構包括邏輯結構圖3.2和物理結構圖3.3兩部分。
從邏輯結構圖,可以看出對資料庫的訪問並沒有完全用預存程序,這是出於運行效率和開發效率的考慮。
這裡的預存程序對每個實體都只包括基本的CRUD四種操作。
3.1 View(視圖)
3.1.1原理
視圖用於管理資訊的顯示,它提供使用者互動介面。使用多個包含單頁面顯示的使用者組件,複雜的Web頁面可以展示來自多個資料來源的內容,並且網頁人員,美工能獨自參與這些Web頁面的開發和維護。在Asp.net下,視圖的實現很簡單。可以像開發WINDOWS介面一樣直接在整合式開發環境下通過拖動組件來完成頁面開發本。每一個頁面也可以採用複合視圖的形式即:一個頁面由多個子視圖(使用者組件)組成;也可以繼承母板頁MasterPage。子視圖可以是最簡單HTML 組件、伺服器組件或多個組件嵌套構而成的Web自訂組件或Web頁面。 頁面都由模板定義,模板定義了頁面的布局,使用者組件的標籤和數目,使用者指定一個模板(這裡的模板指Html頁面、Asp.net頁面、使用者組件等),.net平台根據這些資訊自動建立頁面。針對靜態模板內容,如頁面上的網站 導航,菜單,友情連結,這些使用預設的模板內容配置;針對動態模板內容(主要是業務內容),由於使用者的請求不同,只能使用後期綁定,並且針對使用者的不同,使用者組件的顯示內容進行過濾。使用由使用者組件根據模板配置組成的組合頁面,它增強了可重用性,並簡化了網站的布局。在.Asp.net2.0中,可以使用MasterPage來簡化視圖設計。在MasterPage裡設定的Skin(皮膚),會根據不同子視圖(繼承自MasterPage頁)中的Them(主題)。自動選擇合適的Skin顯示。可以說MasterPage是MVC架構思想的很好體現。
視圖部分大致處理流程如下:首先,頁面模板定義了頁面的布局;頁面設定檔定義視表徵圖簽的具體內容(使用者組件);然後,由頁面配置策略類初始化並載入頁面;每個使用者組件根據它自己的配置進行初始化,載入校正器並設定參數,以及事件的委託等;使用者提交後,通過了展示層的校正,使用者組件把資料自動認可給業務實體即模型。
這一部分主要定義了WEB頁面基類PageBase;頁面配置策略類PageLayout,完成頁面配置,用於載入使用者組件到頁面;使用者組件基類 UserControlBase即使用者控制項架構,用於動態載入檢驗組件,以及實現使用者組件的個人化。為了實現WEB應用的靈活性,視圖部分也用到了許多設定檔例如:模板配置、頁面配置、路徑配置、驗證配置等。
3.1.2實現
良好的介面架構設計,將減少介面調整時間。在.net下應充分利用Asp.net2.0新特性,自動導航,SiteMap、MasterPage、MemberShip、MultiView、Them、Skin等。在本項目中,每個模組的View,實際上都只有兩種,一種是用來顯示多條資料的列表頁面,一種是用來編輯、和查看詳情的頁面。由於View種類幾乎是固定的,所以不需要加入Observer(觀察者)模式。讓所有的編輯頁都繼承自“母板頁dialog.master”,所有列表頁都繼承“母板頁Main.master”即可。3.4
每個列表頁面的動態顯示地區僅為ContentPlaceHolder即黃色地區部分,這就保證相同類型頁面風格的一致。按照命名規範和便於理解的原則,我們把所有的編輯頁尾碼都取名為“EditPG.aspx”,所有的列表頁尾碼都取名為“ListPG.aspx”。對View的改變,可以通過Asp.net2.0的主題(Themes)來實現。本例中編輯和查看詳情頁面,用的就是相同的視圖(View)。如果要添加不同的View,只需添加相應的Master,和完成具體的顯示要求。在本項目中,所有的編輯頁面一般只需要實現基類(DialogUIBase)提供的如下方法。
//得到資料,並存放在對應的Model中,供View使用 protected override void GetDataFromDB(object keyValue){…} //用Model中的資料填充編輯或顯示介面 protected override void SetEditText(){…} //重新填寫編輯框頁面的組件內容, 對部分使用者可能重複填寫的組件內容不進行賦默 認值操作 protected override void ResetEditText(){…} //檢查使用者輸入正確性 protected override string CheckUserInput(){…} //儲存使用者輸入,把使用者輸入更新到資料庫 protected override object SaveEditText(object keyValue){…} 所有的列表View一般也只用實現基類(GridViewUIBase)提供的如下幾個虛方法. //返回子類中使用的GridView,子類必須繼承 protected override GridView GetGridView(){…} // 返回子類中的GridView中複選框列模板中複選框的名稱,子類根據有無該模板列進 行選擇繼承 protected override string GetGridCheckBoxName(){…} 通常無需處理的繼承方法 //綁定DataGrid組件事件, protected override void BindGridEvent(){…} //綁定除通過GetDataGrid()傳入的DataGrid組件以外的組件的用戶端事件 protected override void BindControlEvent(){…} // 返回GridViewList使用的資料來源, 子類必須繼承 protected override object GetDataSource(){…} // 多條記錄刪除,在刪除按鈕事件中調用 protected override void DelRecords(object keyValuesString){…} // 返回以CommandName為key以GridEventPageParam型別參數為內容的hashtable protected override Hashtable GetDialogParams(){…}
從以上代碼中可以很容易發現,無論是列表頁面還是編輯頁面,都沒有和流程相關的東西,這正是MVC所要做的,View中只包含資料的顯示,流程完全由基類控制。好處是顯而易見的。不同的人寫出來的View也具有相同的風格。
3.2 Controller(控制器)
3.2.1原理
Controller控制器是Model與View之間溝通的橋樑,它可以指派使用者的請求並選擇恰當的視圖以用於顯示,同時它也可以解釋使用者的輸入並將它們映射為模型層可執行檔操作。在.NET中每個aspx對應了一個後端代碼aspx.cs,可以通過aspx.cs方便地實現Controller的功能。每個Asp.net頁面都有一種機制,將頁面中的組件所要調用的方法在一個與其分離的類中實現。這些aspx和ascx檔案後端代碼繼承了System.Ul.Web.Page的類執行控制器功能,它包括了各種初始化和控制函數。當載入aspx頁面時將調用Page_ Load事件,當aspx頁面從記憶體中被卸載時將調用Page_UnLoad事件。如果某個組件觸發頁面以使其被重新載入則將調用Control Event事件。
3.2.2實現
對應所有編輯頁面的控制類為DialogUIBase.cs ,該類完成所有編輯頁面的流程式控制制、請求控制 ;對應所有列表頁面的控制類為GridViewUIBase.cs ,該類完成所有列表頁面的流程式控制制和請求控制 ;這兩個類都位於App_Code檔案夾下。
編輯頁面基類(DialogUIBase)和列表頁面基類(GridViewUIBase)都繼承自System.Web.UI.Page,都包含兩部分,一是供View子類繼承的虛方法,一是對View子類流程式控制制的方法。
本例中GridViewUIBase中主要包含的方法有:
供子類繼承的方法#region 供子類繼承的方法 //返回子類中使用的GridView protected virtual GridView GetGridView(){…} //返回子類中的GridView中複選框列模板中複選框的名稱,子類根據有無該模板列進行選擇繼承 protected virtual string GetGridCheckBoxName(){…} // 返回GridView使用的資料來源 protected virtual object GetDataSource(){…} // 刪除View中的選擇的資料 protected virtual void DelRecords(object keyValuesString){…} // 返回以CommandName為key以GridEventPageParam型別參數為內容的hashtable protected virtual Hashtable GetDialogParams(){…} // 綁定GridView組件用戶端事件,通本預設綁定函數綁定的用戶端事件,被繫結資料行的所有行均調用相同的對話方塊頁面,如果要不同的行調用不同的對話方塊頁面則需要重寫該函數 protected virtual void BindGridEvent(){…} //綁定除通過GetGridView()傳入的GridView組件以外的組件的用戶端Click事件 protected virtual void BindControlEvent(){…} //按鈕事件綁定 public void BindBtnEvent(…){…} //表格事件綁定 public void BindGridEvent(…){…}
DialogUIBas類和GridViewUIBase類,設計思路完全相同。所以不再舉例。從上面當面可以發現在GridViewUIBase中,實現了對View的控制。根據使用者的請求的不同,調用不同的Model進行處理。
3.3 Model(模型)
3.3.1原理
Model對象代表了商業規則和商業資料,單個模型代表問題域中的某個對象,或叫做實體。所以模型要封裝系統的應用功能和應用屬性。提供訪問顯示資料的操作,提供控制內部行為的操作以及其他必要的操作介面。模型的構成與具體的應用問題緊密相關。通常模型包括資料訪問、商務邏輯和商務規則。在Asp.net中,簡單的模型可以方便地用自動代碼產生工具實現。VS IDE 2003、VS IDE 2005本身就提供了很好的支援,可以從資料庫或XML等資料來源,輕鬆的產生強型別的DataSet和DataTable。資料訪問層可以使用Application Block塊。或Enterprise Library 等開源組件。當然你也可以手動完成這些工作,如果你願意。
3.3.2實現
在本樣本中,業務處理對象和業務實體物件都繼承自EntityBase類。EntityBase類又繼承自Entity類。Entity類是資料庫訪問的基類。它主要包含供子類繼承的方法(用預存程序完成資料庫的CRUD操作)。和供外部類調用的方法(Model完成CRUD操作)。設定兩種方式是因為邏輯結構的需要。
供子類繼承的主要方法如下:
protected virtual void Init(){…}//執行必要的初始化 protected virtual bool Proc_Insert(){…} //添加 protected virtual bool Proc_Update(object KeyValue) {…} //更新 protected virtual bool Proc_ReadByKeyValue(object KeyValue){…} //檢索 protected virtual bool Proc_Delete(object KeyValue){…} //刪除 protected virtual DataTable Proc_ReadAll(){…} //檢索所有 protected virtual void AfterLoad(){…} //資料庫中資料更新模型之前 protected virtual void BeforeSave(){…}//用模型更新資料庫之前 供外部調用的主要方法如下: public DataTable ReadAll(){…} //檢索所有 public object Insert(){…} //添加 public object Update(object keyValue){…} //更新 public bool Load(object keyValue){…} //填充Model public bool Delelte(object keyValue){…} //刪除 public void Clear() //清除Model
EntityBase類,只需實現基類(Entity)的四個虛CRUD方法,和定義Model自身相關的屬性。由於Model又繼承於EntityBase類,所以如果某個Model需要進行額外的操作,可添加到該Model對應的AfterLoad()或BeforeSave()方法中。
3.4 MVC架構的擴充設計
通過在Asp.net中使用MVC模式,可以構建,具有良好擴充性的Web應用。MVC構架可以輕鬆實現以下功能:
①實現一個模型的多個視圖;
②採用多個控制器;
③當模型改變時,所有視圖將自動重新整理;
④所有的控制器將相互獨立工作。
這就是MVC模式的好處,只需在以前的程式上稍作修改或增加新的類,即可輕鬆增加許多程式功能。以前開發的許多類可以重用,而程式結構根本不再需要改 變,各類之間相互獨立,便於團體開發,提高開發效率。下面討論如何?一個模型、兩個視圖和一個控制器的程式。其中模型類及視圖類根本不需要改變,與前面的完全一樣,這就是物件導向編程的好處。對於控制器中的類,只需要增加另一個視圖,並與模型發生關聯即可。該模式下視圖、控制器、模型三者之間的3.5所示。
同樣也可以實現其它形式的MVC例如:一個模型、兩個視圖和兩個控制器。從上面可以看出,通過MVC模式實現的應用程式具有極其良好的可擴充性,是Asp.net物件導向編程的未來方向。
4 MVC架構的優點及不足4.1 MVC的優點
MVC的優點體現在以下幾個方面:
(1) 有利於團隊開發分工協作和品質控制,降低開發成本。
(2) 可以為一個模型在運行時同時建立和使用多個視圖。變化-傳播機制可以確保所有相關的視圖及時得到模型資料變化,從而使所有關聯的視圖和控制器做到行為同步。
(3) 視圖與控制器的可接插性,允許更換視圖和控制器對象,而且可以根據需求動態開啟或關閉、甚至在運行期間進行對象替換。
(4) 模型的可移植性。因為模型是獨立於視圖的,所以可以把一個模型獨立地移植到新的平台工作。需要做的只是在新平台上對視圖和控制器進行新的修改。
(5) 潛在的架構結構。可以基於此模型建立應用程式架構,不僅僅是用在設計介面的設計中。
4.2 MVC的缺點
MVC的不足體現在以下幾個方面:
(1)增加了系統結構和實現的複雜性。對於簡單的介面,嚴格遵循MVC,使模型、視圖與控制器分離,會增加結構的複雜性,並可能產生過多的更新操作,降低運行效率。
(2)視圖對模型資料的訪問效率低。視圖可能需要多次調用Model才能獲得足夠的顯示資料。
(3)完全理解MVC並不是很容易。使用MVC需要精心的計劃,由於它的內部原理比較複雜,所以需要花費一些時間去思考。 同時由於模型和視圖要嚴格的分離,這樣也給調試應用程式到來了一定的困難。
結束語
與軟體所處理問題的內在模型相比較,使用者介面是需要經常發生變化的,採用MVC設計模式可以在滿足對介面要求的同時,使軟體的計算模型獨立於介面的構成。也可以基於此模型建立大型分布式應用程式架構。
MVC並不適合小型甚至中等規模的應用程式,花費大量時間將MVC應用到規模並不是很大的應用程式通常會得不償失。
MVC是一種軟體開發架構。和其它設計模式一樣,它不是萬能的,也不是一成不變的。要根據具體情況靈活運用。在上面的樣本項目中,為了提高運行和開發效率。在Model設計上就提供了兩種訪問方式。
樣本中的MVC採用了集中控制的方式。一個列表控制器GridViewUIBase,對應多個列表視圖。一個編輯控制器DialogUIBase對應對個編輯、查看詳情視圖。對每個模型而言,僅有兩種視圖,且幾乎是固定不變的。所以沒有增加Observer(觀察者)模式。這樣減少了系統的複雜性。本樣本最精彩的部分,就是控制器的設計。各視圖執行流程完全封裝在控制器中。由於視圖中不含有任何控制資訊,流程資訊。所以視圖編碼人員完全不用瞭解Http的無狀態特性等。對他們而言,開發WebForm和WinForm是一樣的。當然這種設計也有它的不足,如果修改某個視圖的顯示,有可能還要修改相關的控制器。
ASP.NET下MVC設計模式的實現