鐘志東 孟清
摘 要: 網(wǎng)站項(xiàng)目設(shè)計(jì)一般根據(jù)項(xiàng)目規(guī)模、安全要求和團(tuán)隊(duì)工作方式等分別采用不同層次的設(shè)計(jì)構(gòu)架,常用的構(gòu)架有二層模型和三層模型。文章通過ASP.NET4.0(C#)介紹五層構(gòu)架模塊化網(wǎng)站設(shè)計(jì)方法。從系統(tǒng)的安全性和技術(shù)層面把系統(tǒng)橫向分解為五層構(gòu)架模式,再從業(yè)務(wù)功能考慮把系統(tǒng)縱向分塊,使得技術(shù)層次更加分明,模塊耦合度更低,模塊可重用性更高。五層構(gòu)架模塊化設(shè)計(jì)把業(yè)務(wù)邏輯和數(shù)據(jù)庫嚴(yán)格與界面分開,系統(tǒng)安全得到保障,這是網(wǎng)站項(xiàng)目開發(fā)的理想構(gòu)架模型。
關(guān)鍵詞: 網(wǎng)站項(xiàng)目設(shè)計(jì); 五層構(gòu)架; 模塊耦合度; 可重用性; 系統(tǒng)安全
中圖分類號:TP311 文獻(xiàn)標(biāo)志碼:A 文章編號:1006-8228(2013)08-19-03
0 引言
在ASP.NET網(wǎng)站項(xiàng)目設(shè)計(jì)中,常用的系統(tǒng)構(gòu)架模式為二層架構(gòu)和三層架構(gòu)[1],如圖1和圖2所示。安全性要求比較高的系統(tǒng)項(xiàng)目一般都基于三層架構(gòu)方式開發(fā)。
圖1的開發(fā)模式只適應(yīng)于SQLServer數(shù)據(jù)庫的開發(fā),在這種模式中直接通過界面層的數(shù)據(jù)綁定控件調(diào)用SqlDataSource數(shù)據(jù)源,再由數(shù)據(jù)源建立數(shù)據(jù)庫連接,并直接執(zhí)行數(shù)據(jù)庫的查詢語句或存儲過程來操作數(shù)據(jù)庫的數(shù)據(jù)(即增、刪、改和檢索操作),編程比較簡潔。其缺點(diǎn)是完全依賴于SQLServer數(shù)據(jù)庫,直接在界面層執(zhí)行查詢語句系統(tǒng)安全性較差,也不利于團(tuán)隊(duì)開發(fā)的分工協(xié)作。這種模式只適應(yīng)于小型項(xiàng)目的開發(fā)。
圖2的開發(fā)模式由界面層的數(shù)據(jù)綁定控件直接調(diào)用業(yè)務(wù)實(shí)體類。這種模式雖然比使用SqlDataSource數(shù)據(jù)源模式復(fù)雜得多,但其具有很大的靈活性,它結(jié)合ADO.NET技術(shù)實(shí)現(xiàn)對來自不同的數(shù)據(jù)庫或數(shù)據(jù)文件的數(shù)據(jù)進(jìn)行處理,在團(tuán)隊(duì)開發(fā)的項(xiàng)目中被普遍采用。
三層構(gòu)架的擴(kuò)展如圖3所示[2],把中間邏輯層進(jìn)一步拆分為三層,構(gòu)成五層構(gòu)架模式。五層構(gòu)架模型從系統(tǒng)安全和技術(shù)層面把業(yè)務(wù)邏輯層進(jìn)一步拆分為數(shù)據(jù)傳遞層、數(shù)據(jù)轉(zhuǎn)換層和執(zhí)行查詢語句對象層,把業(yè)務(wù)邏輯嚴(yán)格與用戶界面隔離開來,以保障業(yè)務(wù)邏輯和數(shù)據(jù)的安全性。再從業(yè)務(wù)功能出發(fā)橫向分割,使系統(tǒng)更加細(xì)化、模塊化和標(biāo)準(zhǔn)化。把軟件開發(fā)過程設(shè)計(jì)成標(biāo)準(zhǔn)的組裝作業(yè)流程,技術(shù)層次分明,利于團(tuán)隊(duì)各個技術(shù)能力層次的分工協(xié)作。第一層次由掌握網(wǎng)頁前端技術(shù)的技術(shù)人員承擔(dān),第二層次可由初級程序人員承擔(dān),第三層次由比較有經(jīng)驗(yàn)的高級程序人員承擔(dān),第四層次可引用標(biāo)準(zhǔn)的ADO.NET技術(shù)封裝靜態(tài)類,第五層次由比較有經(jīng)驗(yàn)的數(shù)據(jù)庫技術(shù)人員承擔(dān)。
本文通過一個供應(yīng)鏈管理信息系統(tǒng)項(xiàng)目的開發(fā)過程來展現(xiàn)五層構(gòu)架模式的設(shè)計(jì)方法和技術(shù)特點(diǎn)。五層構(gòu)架設(shè)計(jì)一般按照業(yè)務(wù)功能劃分模塊,在同一業(yè)務(wù)模塊再按構(gòu)架層次劃分模塊,對整個系統(tǒng)功能從縱向和橫向進(jìn)行切割。
1 用戶界面設(shè)計(jì)
用戶界面網(wǎng)頁的樣式和布局等技術(shù)這里不作介紹,著重介紹網(wǎng)頁文件的數(shù)據(jù)提交和接受的技術(shù)方法[3-4]。圖4所示是一個采購單的輸入界面,當(dāng)采購單明細(xì)信息的商品數(shù)量輸入并回車時將顯示輸入的所有明細(xì)數(shù)據(jù)記錄,單擊 “確認(rèn)”按鈕則生成一張采購單。
給出本網(wǎng)頁的部分代碼如下:
//實(shí)例化采購功能的數(shù)據(jù)傳遞類
ESCM.BLL.PurchaseManage bll=new ESCM.BLL.PurchaseManage();
//實(shí)例化采購功能的屬性類
ESCM.Model.PurchaseManage model=new
ESCM.Model.PurchaseManage ();
//GridView數(shù)據(jù)綁定
int editIndex=-1;
//執(zhí)行DBAccess靜態(tài)分裝類的ExecuteScalar方法獲取臨時表的最大行記錄
object idno=DBAccess.ExecuteScalar(DBAccess.strConn,
CommandType.Text, "Select MAX(IdNo) From DetailTemp");
//獲取GridView編輯行
if (idno!=DBNull.Value) {
editIndex=Convert.ToInt32(idno)-1;
}
else {
//調(diào)用DBAccess靜態(tài)分裝類的ExecuteNonQuery方法,執(zhí)行查詢語句,在臨時表中插入空記錄
DBAccess.ExecuteNonQuery(DBAccess.strConn,
CommandType.Text, "Insert Into DetailTemp(WareName)
Values('')");
editIndex=0;
}
//把臨時表記錄綁定到GridView并設(shè)置編輯行
gvDetailTemp.DataSource=DBAccess.ExecuteDataset
(DBAccess.strConn, CommandType.Text, "Select * From
DetailTemp");
gvDetailTemp.EditIndex=editIndex;
gvDetailTemp.DataBind();
//采購單添加按鈕事件方法代碼,把界面輸入的數(shù)據(jù)傳遞給屬性類對象
model.SupplierNo=Convert.ToInt32(ddlSupplier.SelectedValue);
model.SupplierFormNo=tbSupplierFormNo.Text.ToString();
model.Buyer=tbBuyer.Text.ToString();
model.PayState=rbPayState.SelectedValue;
model.Maker=lbMaker.Text.ToString();
model.Remark=tbRemark.Text.ToString();
model.PurchaseDate=Convert.ToDateTime
(tbPurchaseDate.Text.ToString());
//執(zhí)行接受數(shù)據(jù)對象的方法
bll.Add(model);
本段代碼展示了用戶界面如何傳遞和接受數(shù)據(jù)的過程。網(wǎng)頁事件方法通過數(shù)據(jù)控件把相關(guān)數(shù)據(jù)傳遞給數(shù)據(jù)傳遞層的model對象,而model對象則作為bll對象的參數(shù)。
2 數(shù)據(jù)傳遞層對象
在數(shù)據(jù)傳遞層中包含兩個用戶自定義類[5],一個是ESCM.Model.PurchaseManage類,這是一個屬性類,該類只包含屬性成員,屬性成員與采購管理功能模塊基礎(chǔ)數(shù)據(jù)表的字段相對應(yīng),其部分代碼如下:
namespace ESCM.Model
{ public class PurchaseManage
{ public int PurchaseNo {set; get;} //采購單編號
public string Buyer {set; get;} //采購員
public string Maker {set; get;} //制單人
public string PayState {set; get;} //付款狀態(tài)
public DateTime PurchaseDate {set; get;} //制單日期
public decimal PurchasePrice {set; get;} //訂購價
…… //其他方法省略
}
}
另一個ESCM.BLL.PurchaseManage類是數(shù)據(jù)傳遞類,通過屬性類對象作為方法參數(shù)傳遞數(shù)據(jù),每個方法體只包含一條語句,即調(diào)用數(shù)據(jù)轉(zhuǎn)換對象的相應(yīng)方法的語句。由它把用戶界面數(shù)據(jù)傳遞給數(shù)據(jù)轉(zhuǎn)換對象,其部分代碼如下:
namespace ESCM.BLL
{ public class PurchaseManagement
{ //實(shí)例化采購管理模塊功能的數(shù)據(jù)轉(zhuǎn)換類
ESCM.DAL.PurchaseManagement dal=new ESCM.DAL
.PurchaseManagement();
//增加采購單信息
public int Add(ESCM.Model.PurchaseManagement model)
{ return dal.Add(model);
}
…… //其他方法省略
}
}
3 數(shù)據(jù)轉(zhuǎn)換層對象
數(shù)據(jù)轉(zhuǎn)換層的任務(wù)是把用戶界面?zhèn)鬟f過來的數(shù)據(jù)轉(zhuǎn)換成數(shù)據(jù)庫查詢語句相匹配的參數(shù),并指定要被執(zhí)行的查詢語句。這一層次的對象還有另外一個重要的角色,就是要承擔(dān)數(shù)據(jù)庫存儲過程難于應(yīng)對的復(fù)雜業(yè)務(wù)邏輯,如隊(duì)列管理等。其部分代碼如下:
namespace ESCM.DAL
{ public class PurchaseManagement
{ //增加采購單信息
public int Add(ESCM.Model.PurchaseManagement model)
{ //把model對象相關(guān)成員屬性轉(zhuǎn)換為Object數(shù)組元素
Object[] paramValures=new object[] { model.SupplierNo,
model.SupplierFormNo,
model.Buyer,
model.PayState,
model.Maker,
model.Remark,
model.PurchaseDate
};
//調(diào)用DBAccess靜態(tài)封裝類的ExecuteNonQuery方法執(zhí)行存儲過程
object obj=DBAccess.ExecuteNonQuery (DBAccess
.strConn, "ProPurchaseFormAdd", paramValures);
}
…… //其他方法省略
}
}
4 執(zhí)行查詢語句層對象
本層的對象是一個通過ADO.NET技術(shù)執(zhí)行各種查詢語句的類,可設(shè)計(jì)為標(biāo)準(zhǔn)的靜態(tài)封裝類,被所有功能模塊引用,更進(jìn)一步地被所有項(xiàng)目引用[6]。該類包含一系列的靜態(tài)重載方法來執(zhí)行各種各樣的查詢語句。微軟提供了標(biāo)準(zhǔn)的封裝類文件sqlhelper.cs,可在網(wǎng)上下載,在此不作贅述。
也可在對安全性要求不高且重用性較低的編碼中,為了簡化編程,直接在界面層調(diào)用本封裝類,如本文網(wǎng)頁代碼中所給出的對臨時表的操作一樣。
5 數(shù)據(jù)庫設(shè)計(jì)
良好的數(shù)據(jù)庫設(shè)計(jì)其基本標(biāo)準(zhǔn)是基礎(chǔ)數(shù)據(jù)表盡可能避免重復(fù)字段,基礎(chǔ)數(shù)據(jù)表要建立必要的關(guān)聯(lián)約束和索引,用視圖組織查詢字段,用存儲過程實(shí)現(xiàn)數(shù)據(jù)的增、刪、改和檢索操作。
6 結(jié)束語
本文以商務(wù)網(wǎng)站系統(tǒng)中采購單信息輸入功能為例,探討了網(wǎng)站開發(fā)中的五層構(gòu)架模塊化設(shè)計(jì)方法。只要掌握了本功能的設(shè)計(jì),就可以此類推,掌握整個系統(tǒng)的五層構(gòu)架模塊化設(shè)計(jì)方法。
五層構(gòu)架模式是三層構(gòu)架的擴(kuò)展,在網(wǎng)站項(xiàng)目開發(fā)中具有如下突出的優(yōu)點(diǎn):
⑴ 代碼安全性比較高,具體的業(yè)務(wù)邏輯和數(shù)據(jù)處理遠(yuǎn)離界面層,系統(tǒng)不易受到攻擊;
⑵ 構(gòu)架層次與技術(shù)層次緊密相關(guān),技術(shù)層次界線分明,比較易于開發(fā)團(tuán)隊(duì)的各個技術(shù)層級的工作分工與協(xié)作;
⑶ 按技術(shù)層面和業(yè)務(wù)功能劃分模塊,系統(tǒng)耦合性比較低;
⑷ 代碼重用性比較高,設(shè)計(jì)的中間業(yè)務(wù)層類很容易引用到其他的類似項(xiàng)目中;
⑸ 類方法技巧的重用性比較高,在一個業(yè)務(wù)功能模塊比較好的設(shè)計(jì)方法可以直接引用到另一個功能模塊中;
⑹ 每個過程技術(shù)分明,關(guān)聯(lián)性明確,易于標(biāo)準(zhǔn)化設(shè)計(jì)。
五層構(gòu)架模塊化系統(tǒng)設(shè)計(jì)不僅適用于網(wǎng)站項(xiàng)目的開發(fā),也適用于所有管理信息系統(tǒng)項(xiàng)目的開發(fā)。
參考文獻(xiàn):
[1] 戴上平,丁士鋒等.ASP.NET3.5完全自學(xué)手冊[M].機(jī)械工業(yè)出版社,2009.
[2] 鐘志東.趙中文等.ASP.NET 4(C#)項(xiàng)目開發(fā)教程——面向工作過程[M].北京航空航天大學(xué)出版社,2011.
[3] 溪江華.圣殿祭司的ASP.NET2.0開發(fā)詳解[M].電子工業(yè)出版社,2006.
[4] 馬偉.ASP.NET 4權(quán)威指南[M].機(jī)械工業(yè)出版社,2011.
[5] 周禮.C#和.NET3.0第一步[M].清華大學(xué)出版社,2008.
[6] 微軟.Sqlhelper類[DB/OL].百度百科.