實戰揭祕:開發.Net平臺應用系統框架

實戰揭祕:開發.Net平臺應用系統框架
作者:孫亞民    本文選自:賽迪網
微軟的.Net平臺給應用程序開發提供了一個非常好的基礎系統平臺,但是,如何在這個系統平臺上構建自己的應用系統,還需要我們針對應用系統的特點,構建自己的應用系統框架(Framework)。我們在應用.Net開發系統的過程中,結合多年的開發經驗,也參考了J2EE的架構,設計了一套.Net下的應用系統框架,以及相應的中間件和開發工具,已經在多個項目中和軟件產品中應用,取得了很好的效果。現在向代價介紹這個框架的整體解決方案,希望對您有所幫助。

我們知道,對於典型的三層應用系統來說,通常可以把系統分成以下三個層次:

· 數據庫層

· 用戶界面層

· 應用服務層

對於應用系統來說,在這三個層次中,系統的主要功能和業務邏輯在應用服務層進行處理,對於系統框架來說,主要處理的也是這個層次的架構。

對於應用服務層來說,在一個面向對象的系統中,以下幾個方面的問題是必須要處理的:

· 數據的表示方式,也就是實體類的表示方式,以及同數據庫的對應關係,即所謂的O-R Map的問題。

· 數據的存取方式,也就是實體類的持久化問題,通常採用數據庫來永久存儲數據實體,這就需要解決同數據庫的交互問題。這個部分要完成的功能,就是將數據實體保存到數據庫中,或者從數據庫中讀取數據實體。同這個部分相關的,就是對數據訪問對象的使用。在框架中,我們對ADO.Net又做了一層封裝,使其使用更加簡便,同時也統一了對ADO.Net的使用方式。

· 業務邏輯的組織方式。在面向對象的系統中,業務邏輯是通過對象間的消息傳遞來實現的。在這個部分,爲了保證邏輯處理的正確性和可靠性,還必須支持事務處理的能力。

· 業務服務的提供方式。爲了保證系統的靈活性和封裝性,系統必須有一個層來封裝這些業務邏輯,向客戶端提供服務,同時作爲系統各個模塊間功能調用的接口,保證系統的高內聚和低耦合性。這裏的客戶指的不是操作的用戶,而是調用的界面、其他程序等。Web層(ASP.Net頁面)通常只同這個部分交互,而不是直接調用業務邏輯層或者數據實體的功能。

爲了能夠很好的解決這些問題,我們設計了這個框架。在框架中,針對以上問題,我們將應用服務層又劃分成五個層次:數據實體層、實體控制層、數據訪問層、業務規則層和業務外觀層。各個層次同上述問題的關係可以用表表示如下:

層次 問題
數據實體層 數據的表示方式
實體控制層 數據的存取方式
數據訪問層 提供對數據庫的訪問,封裝ADO.Net
業務規則層 業務邏輯的組織方式
業務外觀層 業務服務的提供方式



整個系統的結構圖如下:

CSDN_Dev_Image_2003-7-61228131.gif


圖中的箭頭表示使用關係

將系統劃分成這麼多層次,其好處是能夠使得系統的架構更加清晰,這樣每個層次完成的功能就比較單一,功能的代碼有規律可循,也就意味着我們可以開發一些工具來生成這些代碼,從而減少代碼編寫的工作量,使得開發人員可以將更多的精力放到業務邏輯的處理上。正是基於這個想法,我們同時開發了針對這個框架的開發工具,並在實際工作中減少很多代碼的編寫量,效果非常好。同時,爲了應用服務層更好的工作,我們設計了一個支持這個框架的應用系統中間件。(現在,已經有多家其他公司在試用這個中間件系統。)

同J2EE的EntityBean不同的是,我們採用了數據實體和實體控制分開的設計方法,這樣的做法會帶來一定的好處。

下面我將各個部分的設計方案和策略詳細介紹如下:

數據實體層

我們首先需要解決的是數據的表示方式的問題,也就是通常的O-R Map的問題。

O-R Map通常的做法是將程序中的類映射到數據庫的一個或多個表,例如一個簡單的Product類:



在數據庫中可能對應了一張Product表:

字段名 數據類型
ProductID Varchar(40)
ProductName Varchar(50)
Account float



這是最通常的做法,但是,由這種方式會帶來一些問題。首先就是數據實體在數據庫和程序中的表現方式不一樣,對於一些涉及到多個表的“粗粒度對象”,一個實體類可能會引用到多個其它實體類,也就是說會在涉及到對象粒度的建模方面帶來一些問題;其次在同數據庫交互時,也涉及到一個轉換的問題,如果一個對象涉及到對多個表的操作,問題就更大;最後,當系統做查詢操作,需要返回多個對象時,因爲涉及到轉換的問題,效率就比較低下,而如果採用直接返回數據集的方式,雖然能夠提高效率,又會帶來數據表達方式不一致的問題。

考慮到上述問題,我們在數據實體的表現上採用了另外一種方式,那就是利用DataSet。DataSet是微軟在ADO.Net中新提出的數據對象,同ADO的Recordset不同的是,他能夠容納多個記錄集。DataSet類似於一個內存數據庫,由多個DataTable組成,而一個DataTable又有多個Column。這樣的結構,使得他可以同數據庫很好的進行映射。同時,我們吸取了J2EE架構中CMP使用XML文件定義實體類結構的優點,採用了類似的解決方案。

因此,在這個方面我們是這樣來進行處理的:

1) 核心類庫定義了EntityData類,這個類繼承了DataSet,添加了一些方法,用來作爲所有實體類的框架類,定義了各個實體類的一般結構,至於每個實體類具體的結構,在運行時刻由下述辦法確定:

2) 實體類的定義通過XML文件來確定,該XML文件符合JIXML對象實體描述語言的規範(注:JIXML是我們開發的 對象-實體 映射語言),用於確定實體類的結構。例如,一個關於訂單的實體類的定義可能類似於下面的結構:

3) 實體對象的結構由一系列的類構造器在運行時刻,根據上述規範制定的XML來生成。這些類構造器實現IClassBuilder接口。我們在系統核心類庫中預定義了一些標準的Builder,一般情況下,直接使用這些標準的Builder就可以了。

類構造器採用的類構造工廠的設計模式,如果使用者覺得標準的Builder不能滿足要求,也可以擴展IClassBuilder接口,編寫自己的類構造器,然後在系統配置文件中指明某各類的類構造器的名稱即可。

IClassBuilder的定義如下:



這個部分的結構可以用類圖表示如下:

CSDN_Dev_Image_2003-7-61228133.gif


當使用者需要某個實體類的時候,只要採用如下語句:



EntityDataManager的GetEmptyEntity方法通過調用ClassBuilder的BuildClass來實現,並且實現對象的緩存功能。

ClassBuilder的BuildClass方法實現如下:



這兒綜合使用了Builder和Factory的設計模式。ClassBuilderFactory的作用是根據實體類的名稱,讀取配置文件中相應的類構造器的具體類名,並返回具體的類構造器。

配置文件ClassBuilders.xml的結構很簡單:



如果沒有爲某個實體類指明具體的Builder,系統將調用默認的Builder來構造實體對象的結構。

系統同時提供了實體對象緩存服務。通過上述方式產生的實體對象可以被緩存,這樣,在第二次調用該對象時,可以從緩存中讀取,而不用從頭重新生成,從而大大提高了系統的性能。

在實際的開發過程中,我們感覺到,數據實體層採用這種設計模式具有以下優點:

· 實體類定義XML文件可以通過工具來自動生成,減輕開發工作量。

· 在執行查詢操作時,不論是返回一個實體,還是多個實體,數據的表現方式都一樣,都是EntityData,而不存在如上面所述的單個對象和數據集的表現方式不統一的問題。

· 在修改實體類的定義時,如果修改的部分不涉及到業務邏輯的處理,只需要修改XML文件就可以了,不用修改其它程序和重新編譯。

· 系統提供的實體對象緩存服務可以大大提高了系統的性能。

· 類構造工廠的設計模式大大提高了系統的靈活性。

實體控制層

解決和O-R Map的問題,需要考慮的就是實體類的持久性問題了,也就是同數據庫的交互問題。實體控制層用於控制數據的基本操作,如增加、修改、刪除、查詢等,同時爲業務規則層提供數據服務。

實體控制層的類實現IEntityDAO接口。這個接口定義了實現數據操縱的主要必要方法,包括增加、修改、刪除和查找。IEntityDAO的定義如下:



可以看到,這個接口同J2EE中EntityBean的接口定義很象,實際上,我們也是參考了EntityBean的解決方案。

下面是一個Product的DAO類的例子:



同數據實體層相結合,這兩部分實現了應用服務層同數據庫的交互。這兩個部分結合,完成了類似於J2EE中EntityBean的功能。

採用數據實體和實體控制分開的設計方法,具有以下優點:

· 避免了J2EE體系中操縱EntityBean系統資源消耗大,效率低下的缺陷。

· 解決了J2EE體系中使用EntityBean傳輸數據時開銷大,過程複雜、效率低的缺陷。

· 可以單獨修改實體結構和對實體數據的操縱,使得系統更加靈活

· 數據實體的XML定義文件和實體控制層的類可以通過工具自動生成,減輕開發工作量。

數據訪問層

爲了爲實體控制層提供對數據庫操作的服務,我們設計了這個部分。這個層次通常執行以下一些操作:

· 連接數據庫

· 執行數據庫操作

· 查詢數據庫,返回結果

· 維護數據庫連接緩存

· 數據庫事務調用

爲了統一對數據的訪問方式,我們在設計的時候,在框架的類庫中包含了數據訪問服務,封裝了常用的對各種數據庫的操作,可以訪問不同類型的數據庫,這樣,在具體軟件系統開發的時候,可以不用考慮同數據庫的連接等問題,也使得應用系統在更換數據庫時,不用修改原有的代碼,大大簡化了開發和部署工作。數據訪問服務還維護數據庫連接緩存,提高系統性能,以及對數據庫事務調用的服務。

數據訪問服務在覈心類庫中主要通過DBCommon類來提供對數據訪問功能調用的服務。DBCommon的使用方法在上面的ProductEntityDAO中可以看出一二。更多的可以看看Demo工程中的使用。

業務規則層

業務規則層需要完成的功能是各種業務規則和邏輯的實現。業務規則完成如客戶帳戶和書籍訂單的驗證這樣的任務。這是整個應用系統中最爲複雜的部分,沒有太多的規律可循。但是,我們在完成上面的工作後,對於這個部分的開發,也可以起到一定的簡化的工作。這從下面的例子可以看到。

業務規則層的設計通常需要進行很好的建模工作。業務規則的建模,一般採用UML來進行。可以使用UML的序列圖、狀態圖、活動圖等來爲業務規則建模。這個部分的工作,通常通過一系列的類之間的交互來完成。

業務規則通常要求系統能夠支持事務處理(Transaction)。在這個地方,.Net提供了很方便的調用Windows Transaction Server的手段。關於這個部分的內容,各位自己閱讀MSDN就非常清楚了,這裏就不做詳細的介紹了。

例如,在一個庫存系統的入庫單入庫操作中,除了需要保存入庫單外,在這個之前,還必須對入庫單涉及的產品的數量進行修改,其代碼通常如下(使用了事務處理):

 

業務外觀層

業務外觀層爲 Web 層提供處理、瀏覽和操作的界面。業務外觀層用作隔離層,它將用戶界面與各種業務功能的實現隔離開來。

業務外觀層只是將已經完成的系統功能,根據各個模塊的需要,對業務規則進行高層次的封裝。

框架沒有規定採用在業務外觀層採用何種實現方式,但是建議使用Web Service來提供服務。採用IIS爲Web服務器,可以很方便的部署Web Service。

· Web層

Web 層爲客戶端提供對應用程序的訪問。Web 層由 ASP.NET Web 窗體和代碼隱藏文件組成。Web 窗體只是用 HTML 提供用戶操作,而代碼隱藏文件實現各種控件的事件處理。

通常,對於數據維護類型的ASP.NET Web 窗體和控件事件處理代碼,我們提供了工具來生成,減輕開發工作量。

除了上述6個邏輯層以外,系統通常還包括一個系統配置項目,提供應用程序配置和跟蹤類。

框架服務的設計策略

爲了能夠很好的支持上面所述的系統架構,我們需要一套核心的類庫,以實現對構築其上的應用軟件的支持。這樣,在具體每個應用系統的開發時,可以省略很多基礎性的工作,提高開發的效率。在這個方面,我們設計了以下核心類和接口:

· EntityData:定義實體類的通用結構

· IClassBuilder:定義實體類結構構造的結構。我們預定義了根據這個接口實現的幾個標準類:AbstractClassBuilder、SingletableClassBuilder、ThickClassBuilder、StandardClassBuilder。這些Builder通過ClassBuilderFactory進行管理。

· IEntityDAO:定義實體控制類的接口

· EntityDataManager:提供對所有實體類的緩存管理和查找服務

· DBCommon:封裝數據庫操作

· ApplicationConfiguration:記錄系統配置

· SqlManager:管理系統的SQL語句及其參數。

通過這些核心的類和接口,框架能夠爲應用系統提供如下服務:

· O-R Map:對象-關係數據庫映射服務

這部分完成應用程序中的實體對象同關係型數據庫的映射,主要爲數據實體層提供服務。

在這個部分中,定義了JIXML實體-對象映射語言。這是我們開發的一種使用XML來描述對象-實體間的映射關係的規範語言,開發者可以使用它來描述對象-實體間的映射關係。開發者也可以直接擴展IClassBuilder接口,手工完成對象-實體間映射關係的代碼。系統在運行時刻,會根據配置文件的設置,調用實體類的構造器,動態構造出實體對象的結構。

· Database Access:數據庫訪問服務

這個部分提供對數據庫訪問的服務。在這個框架上構建的應用軟件系統,不直接操縱數據庫,而是通過類庫提供的數據訪問服務來進行。數據庫訪問服務作爲應用程序同數據庫之間的中介者,能夠有效防止對數據庫的不安全操作。

數據庫訪問服務同時提供了對數據庫庫事務處理的調用方法,開發者可以很方便的通過數據庫訪問服務調用數據庫的事務處理功能。

· DML Search:數據操縱語句查詢服務

在系統架構中,對數據庫進行操作的SQL語句不在程序中硬編碼,而是同數據實體層的實體類結構一樣在XML文件中描述,其結構符合JIXML規範。這些操縱語句中的基本部分,如數據的插入、刪除、修改、查詢等語句,可以通過我們自己開發的工具生成。這樣,在系統的便於修改性和靈活性上能夠得到很大的提高。這樣一來,系統必須提供這些數據操縱語句的查詢服務。核心類庫提供了在XML文件中查找這些數據操縱語句和相關參數的服務。

· Entity Buffer&Search:實體對象緩存&查找服務

系統中的實體對象在第一次創建後,就被系統緩存起來,當系統第二次需要訪問該對象時,不需要再從頭創建這個對象,而只需要從緩存中取出即可。這就是框架提供的實體對象緩存服務。同這個服務相關聯的是實體對象的查找服務,即從這些緩存的實體對象中尋找相應的實體對象的服務。

· Transaction:事務處理服務

我們充分利用Windows COM+事務處理機制的強大功能,使在應用程序能夠充分使用事務處理的功能,保證應用系統的穩定性和可靠性。

當某個類需要使用事務處理功能時,首先使該類繼承System.EnterpriseServices名稱空間下的ServicedComponent類,然後使用如下方式申明該類使用的事務類型:[Transaction(TransactionOption.Required)]。系統在該類第一次被調用時,自動在COM+服務中註冊中該類,使得應用程序可以使用COM+的事務處理功能。

系統支持如下幾種事務處理類型:

成員名稱 說明
Disabled 忽略當前上下文中的任何事務。
NotSupported 使用非受控事務在上下文中創建組件。
Required 如果事務存在則共享事務,並且如有必要則創建新事務。
RequiresNew 使用新事務創建組件,而與當前上下文的狀態無關。
Supported 如果事務存在,則共享該事務。



同時,爲了簡化開發,我們還爲這個框架設計了一個開發工具,並且作爲插件集成到VS.Net的開發環境中,能夠大大減少開發的代碼編寫工作量。

這樣,通過以上這些工作,我們達到了以下目標:

· 有了一個非常清晰的系統架構

· 因爲有了一套核心的類庫來爲應用系統提供服務,使得我們在後面的開發過程中可以減少很多基礎性的工作

· 有了自己的有針對性的開發工具,能夠減少大量的重複編碼的工作。

爲了讀者能夠更好的瞭解系統的結構,附上一個Demo工程(下載Demo工程)。這是一個簡單的倉庫入庫的示例,基本上展示了這個框架的應用系統的結構和核心類庫的使用。

不得不看得實戰內容:利用.Net框架開發應用系統

作者簡介:孫亞民,1998年畢業於南京大學,現任蘇州迪訊軟件開發有限公司技術總監,熟悉J2EE架構、.Net以及C#語言。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章