梁啟恒
摘要:文章對.NET三層架構(gòu)的耦合性進(jìn)行了探討,提出一種利用強(qiáng)數(shù)據(jù)類型數(shù)據(jù)集和反射、泛型技術(shù)對數(shù)據(jù)訪問層進(jìn)行解耦的開發(fā)模型并實(shí)現(xiàn)之,進(jìn)一步降低三個(gè)層次之間的耦合度。
關(guān)鍵詞:數(shù)據(jù)訪問層;解耦;反射;泛型;三層架構(gòu)技術(shù)
0引言
我們開發(fā)業(yè)務(wù)系統(tǒng),都會希望這個(gè)業(yè)務(wù)系統(tǒng)具備模塊化、松耦合的特性,這樣可以達(dá)到快速開發(fā)和適應(yīng)業(yè)務(wù)系統(tǒng)變更的目的。
1三層架構(gòu)
通常意義上的三層架構(gòu)(3-tier architecture)就是將整個(gè)系統(tǒng)從上至下劃分為:表示層(UI)、業(yè)務(wù)邏輯層(BLL)、數(shù)據(jù)訪問層(DAL)。區(qū)分層次的目的體現(xiàn)了“高內(nèi)聚,低耦合”的思想,三個(gè)層次各負(fù)其責(zé),相對獨(dú)立。數(shù)據(jù)訪問層僅僅負(fù)責(zé)對數(shù)據(jù)庫的增刪查改,功能可以很簡單。業(yè)務(wù)邏輯層負(fù)責(zé)從數(shù)據(jù)訪問層獲取數(shù)據(jù),根據(jù)業(yè)務(wù)邏輯對數(shù)據(jù)進(jìn)行處理,并將處理結(jié)果提供給表示層進(jìn)行顯示。表示層一般是通過用戶界面,將用戶的輸入(請求)經(jīng)過簡單處理,提交給表示層,然后把表示層返回的結(jié)果在用戶界面上顯示。
2三層架構(gòu)的解耦
三層架構(gòu)的優(yōu)勢,是各司其職,降低耦合。耦合度的衡量,可以通過考察三個(gè)層次之間的依賴關(guān)系。依賴關(guān)系越緊密,耦合度越高。耦合度高的稱之為緊耦合,反之稱為松耦合。我們的目標(biāo)就是降低三層之間的依賴關(guān)系,如:在數(shù)據(jù)訪問層發(fā)生改變時(shí),業(yè)務(wù)邏輯層不需要做出修改或盡量少修改。松耦合的三層架構(gòu)有助于我們快速開發(fā)應(yīng)用,也有助于我們靈活地增添業(yè)務(wù)模塊。
本文的目的,就是提出一種在NET三層架構(gòu)中對數(shù)據(jù)訪問層進(jìn)行解耦的快速開發(fā)模型并實(shí)現(xiàn)之。
3數(shù)據(jù)訪問層的解耦模型
通常在三層架構(gòu)中,數(shù)據(jù)訪問層與數(shù)據(jù)庫的耦合度很高。雖然數(shù)據(jù)訪問層功能較簡單,主要是實(shí)現(xiàn)數(shù)據(jù)的增刪查改。但是在實(shí)際的開發(fā)實(shí)踐中,這一部分的開發(fā)往往需要開發(fā)人員編寫大量的SQL語句,如果數(shù)據(jù)表發(fā)生改變,幾乎所有有關(guān)的增刪查改的SQL語句都需要修改,增加了升級和維護(hù)的工作量,且極易出錯(cuò)。
解決辦法是,我們可以通過使用.NET框架下的強(qiáng)數(shù)據(jù)類型數(shù)據(jù)集DataSet,建立模型類Model,利用反射和泛型,實(shí)現(xiàn)數(shù)據(jù)訪問層的解耦。反射可以將Model和DataSet的數(shù)據(jù)表進(jìn)行自動(dòng)映射轉(zhuǎn)換,使得我們在執(zhí)行增刪查改操作時(shí)不必關(guān)心字段參數(shù),只需模型類的屬性與數(shù)據(jù)表字段一一對應(yīng)即可。利用泛型則解決了多表的問題:實(shí)現(xiàn)一個(gè)泛型類,就可以對應(yīng)所有數(shù)據(jù)表的增刪查改操作,而不需要對每張數(shù)據(jù)表都編寫一個(gè)數(shù)據(jù)訪問類。泛型簡化了代碼,也降低了DAL與數(shù)據(jù)庫的耦合度。增加一個(gè)數(shù)據(jù)表,或是修改數(shù)據(jù)表,只需要更新DataSet和Model,就可以實(shí)現(xiàn)對新數(shù)據(jù)表的增刪查改操作,大大降低代碼的維護(hù)量。
泛型實(shí)現(xiàn)的關(guān)鍵就是新增的模型類Model。模型類是數(shù)據(jù)表的實(shí)體類,要求其對外公開的屬性與數(shù)據(jù)庫表的字段具有一一對應(yīng)關(guān)系。DAL、BLL、UI三層分別引用Model,Model事實(shí)上成為各層訪問數(shù)據(jù)的接口定義。利用反射機(jī)制使模型類和數(shù)據(jù)訪問類泛型化,進(jìn)一步抽象,統(tǒng)一外部對各數(shù)據(jù)表的訪問,從而降低各層之間的耦合度,更是數(shù)據(jù)訪問層解耦的關(guān)鍵之處。(圖1)
4 DAL解耦模型的實(shí)現(xiàn)
4.1強(qiáng)數(shù)據(jù)類型數(shù)據(jù)集DataSet
DataSet可以在VS IDE中通過拖動(dòng)數(shù)據(jù)源快速生成各數(shù)據(jù)表的實(shí)例。使用強(qiáng)數(shù)據(jù)類型數(shù)據(jù)集,各數(shù)據(jù)項(xiàng)都有明確的類型定義,如果類型不符,編譯就會出錯(cuò)。這樣有兩個(gè)好處,一是減少出錯(cuò)機(jī)會,二是可以快速生成,減少代碼的編寫,VS支持直接拖動(dòng)數(shù)據(jù)表生成實(shí)例,不用編寫一句代碼。在DataSet中,每個(gè)數(shù)據(jù)表適配器TableAdapter都是訪問對應(yīng)數(shù)據(jù)表的接口類,如userTableAdapter是訪問user數(shù)據(jù)表的接口類。在DAL中通過初始化TableAdapter來訪問數(shù)據(jù)表。我們?yōu)槊總€(gè)數(shù)據(jù)表適配器TableAdapter添加增刪查改方法,如InsertQuery、UpdateQuery等。為方便BLL的數(shù)據(jù)處理,InsertQuery應(yīng)添加select@@identity,并將ExecuteMode更改為Scalar模式,以返回新增數(shù)據(jù)的Identity值,即ID值。
4.2泛型數(shù)據(jù)適配器DataAdapter
為了簡化對數(shù)據(jù)庫的訪問,在DAL添加一個(gè)訪問數(shù)據(jù)集的泛型數(shù)據(jù)適配器DataAdapter,使用泛型聲明,如:
public class DataAdapter
where T:class,Hew()
where D:class,new0
其中,T為模型類,D為數(shù)據(jù)表適配器TableAdapter。DAL對所有數(shù)據(jù)表的訪問都可以通過DataAdapter來實(shí)現(xiàn)。如前文所述,這個(gè)泛型數(shù)據(jù)適配器可以適應(yīng)對所有數(shù)據(jù)表的訪問操作。
泛型數(shù)據(jù)適配器DataAdapter是這個(gè)模型的核心,其實(shí)現(xiàn)方法是:①首先聲明并初始化一個(gè)數(shù)據(jù)表適配器的泛型變量,private D adapter=new D(),adapter變量就代表了所有的數(shù)據(jù)表適配器TableAdapter。②創(chuàng)建一個(gè)方法getProperties,把模型實(shí)體類T轉(zhuǎn)換為訪問數(shù)據(jù)表的參數(shù)對象列表。③創(chuàng)建一個(gè)輔助類ModelConvertHelper