《ASP NET程序設計案例教程》課件第9章_第1頁
《ASP NET程序設計案例教程》課件第9章_第2頁
《ASP NET程序設計案例教程》課件第9章_第3頁
《ASP NET程序設計案例教程》課件第9章_第4頁
《ASP NET程序設計案例教程》課件第9章_第5頁
已閱讀5頁,還剩68頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

第9章應用程序架構9.1應用程序架構9.2校園在線超市系統(tǒng)多層架構實現(xiàn)

【本章提要】

本章介紹了企業(yè)級應用多層設計的模式,闡述了應用分層的好處。并以校園在線超市用戶注冊模塊為例,詳細介紹了系統(tǒng)分層架構的實現(xiàn)過程。

【學習目標】

·理解從兩層架構發(fā)展成多層架構。

·掌握將多層體系架構的理念融入到Web應用項目的設計和實施方法。

9.1.1將應用分層的好處

在大型公司里往往運行著大規(guī)模的軟件系統(tǒng),開發(fā)人員和分析師們專注于不同的應用層級。這確實是必須的,因為不可能讓開發(fā)人員都理解某個層級所有的運行細節(jié),若那樣,則系統(tǒng)實在是太龐大了。

9.1應用程序架構想象一下某個保險公司里的應用程序必須完成的所有功能。從最簡化的流程來說,保險公司要能接收新的保險單,評估與保險單相關的風險,向投保者開出賬單,打印保險單然后將它郵寄出去,處理保險單的索賠,更新保險單,如果過期(或者沒有支付費用)則取消保險單,等等。這一巨大的流程顯然不僅僅是一個桌面應用程序所能處理的。

無論用戶是不是想這么做,Web應用還是分層的好。如果用戶是用SQLServer數(shù)據(jù)庫存儲數(shù)據(jù)的,那么數(shù)據(jù)庫本身就已經(jīng)是一個從Web服務器上分離出來的層了(即使物理上它們是在同一臺計算機里)。作為一個面向?qū)ο蟮钠脚_,ASP.NET使得這種分層操作更加容易了。應用程序分層使得整個開發(fā)更加容易,因為分層將某些特定目的操作封裝成一個個獨立的模塊,它們可以單獨維護和修改,同時也分散了維護的工作量。

例如,一個簡單的在線零售程序采用了分層的思想,如圖9-1所示。

從圖中可以看出物理硬件分層與應用程序分層的結合。實際上有三個分層運行于一個Web服務器上,第一層是Web站點的用戶界面層(UserInterface),它由業(yè)務規(guī)則層支持,業(yè)務規(guī)則層(BusinessRulesLayer)決定什么樣的數(shù)據(jù)將被提供給用戶界面層,業(yè)務規(guī)則層與數(shù)據(jù)訪問層交互,而數(shù)據(jù)訪問層則通過一個事務通道程序來獲取所需要的數(shù)據(jù),其他的客戶服務和倉庫系統(tǒng)也通過事務通道程序來獲得所需的數(shù)據(jù)。

圖9-1在線零售應用程序的分層每一層都僅僅關注于自身的功能實現(xiàn),如業(yè)務規(guī)則層不需要知道任何關于數(shù)據(jù)存儲方面的信息,它只需要了解由數(shù)據(jù)訪問層提供的接口即可。事實上,業(yè)務規(guī)則層完全不必關心使用什么樣的數(shù)據(jù)庫,或者是否存在一個數(shù)據(jù)庫。它只需要了解有一個數(shù)據(jù)訪問層能用于交互,以及它可以通過一個公共的接口來交互數(shù)據(jù)即可。

盡管整個系統(tǒng)的完善需要集成測試,但是如果各層之間一致認同的接口沒有發(fā)生改變,則我們可以在不干擾其他層的情況下改變?nèi)魏我粚拥膬?nèi)部結構。9.1.2n級架構

任何關于應用程序架構的討論中,如果沒有提到經(jīng)典的n級架構,那么就是不完整的。“n”代表任何數(shù)字,適用于描述我們所創(chuàng)建的應用程序。層(layer)或級(tier)的數(shù)目,由應用程序塊的需求和結構來決定。

一般而言,甚至最基本的Web應用程序都能夠被分離成三層:用戶界面層(UI)、業(yè)務規(guī)則層(BusinessRulesLayer)以及數(shù)據(jù)層(DataLayer)。用戶界面層就是用戶能夠見到的HTML和Web控件,業(yè)務規(guī)則層則承擔著應用程序最重要的角色,而數(shù)據(jù)層則是數(shù)據(jù)庫或者其他數(shù)據(jù)訪問代碼,這取決于應用程序的結構。如果需要,可以將應用程序分得更細:用戶可以擁有用戶界面(.aspx頁面)、作為用戶界面“粘合劑”而被頁面繼承的類或局部類、業(yè)務規(guī)則層(業(yè)務規(guī)則類)、數(shù)據(jù)訪問層(數(shù)據(jù)訪問類)以及數(shù)據(jù)層本身(數(shù)據(jù)庫)。

假如由于某種原因,決定將SQLServer數(shù)據(jù)庫替換為Oracle數(shù)據(jù)庫,則如果沒有將應用程序分層,而且把數(shù)據(jù)訪問代碼放在.aspx頁面里,那么用戶將不得不冒著把事情搞砸的風險,檢查所有頁面。這顯然不是一種有效的代碼管理方式。實際上,每個頁面間操作數(shù)據(jù)的方式都不同。如果把所有的數(shù)據(jù)訪問代碼都放在單個層里,如一個擁有操作數(shù)據(jù)方法的類,這樣就可以在不破壞業(yè)務規(guī)則或者用戶界面的情況下對代碼進行修改。

另一種很常見的情況是,假設在電子商務程序中,業(yè)務規(guī)則要求改變稅款的計算方式,數(shù)據(jù)庫沒有變化,站點本身也不需要變化,僅僅是邏輯改變了,那就意味著只需要改變業(yè)務規(guī)則層中的類即可。再者,如果邏輯將創(chuàng)建在頁面中或者是由某些數(shù)據(jù)庫存儲過程的計算所組成的,那么這項修改操作將變得十分困難。在一個極端的例子里,稅率可能經(jīng)常改變,那么就不能將稅率硬編碼到代碼中。一般的解決方式是將稅率存儲在數(shù)據(jù)庫中,并創(chuàng)建用戶易于操作的相關工具。

9.2.1系統(tǒng)架構設計

微軟

.NET平臺可以方便快速地開發(fā)和部署多層架構應用程序。在校園在線超市系統(tǒng)中,其架構在邏輯上劃分成數(shù)據(jù)實體層(DML)、數(shù)據(jù)訪問層(DAL)、業(yè)務邏輯層(BLL)和應用層(UI)四層,如圖9-2所示。9.2校園在線超市系統(tǒng)多層架構實現(xiàn)

圖9-2系統(tǒng)分層架構設計從圖中看出,這種分層結構易于理解,同時也使應用程序的維護和修改變得更加容易。假定我們要為MicrosoftAccess數(shù)據(jù)庫創(chuàng)建一個新的數(shù)據(jù)訪問層,則只需要改變數(shù)據(jù)訪問層代碼即可。通過用戶界面進行的輸入和輸出數(shù)據(jù)的過程,實際上是在創(chuàng)建業(yè)務邏輯層的各種對象。例如,在應用程序中添加一個新的商品時,只需要創(chuàng)建一個商品對象,而不需要了解任何關于數(shù)據(jù)庫中的具體細節(jié)。下面以“用戶注冊模塊”為例,說明校園在線超市系統(tǒng)的多層實現(xiàn)過程。為了區(qū)分校園在線超市兩層實現(xiàn)的定義,這里將解決方案命名為“NetShop”,在數(shù)據(jù)庫設計和命名上也做一些改進。9.2.2數(shù)據(jù)實體層實現(xiàn)

數(shù)據(jù)實體層(DML,DataModelLayer)主要功能是實現(xiàn)關系數(shù)據(jù)庫實體和實體關系表到應用程序?qū)ο蟮挠成洹?shù)據(jù)庫中有名為“Users”的實體表,用來存儲注冊用戶的相關信息。打開VS2005,創(chuàng)建一個新網(wǎng)站,新建名為“Model”的文件夾,命名空間為“NetShop.Model”,在該文件夾下添加類庫文件User.cs,創(chuàng)建用戶類。相應代碼編寫如下:

usingSystem;

namespaceNetShop.Model

{

//<summary>

//實體類Users(屬性說明自動提取數(shù)據(jù)庫字段的描述信息)

//</summary>

[Serializable]

publicclassUsers

{

publicUsers()

{}

#regionModel

privateint_s_id; //用戶ID

privatestring_s_name; //用戶名稱

privatestring_s_password; //用戶密碼

privatestring_s_qq; //用戶QQ

privatestring_s_email; //Email

privatestring_s_phone; //聯(lián)系電話

privatestring_s_address; //通信地址

privatestring_s_sex;//性別

privatestring_s_idcard; //身份證號

privateDateTime?_s_date; //出生日期

privatestring_s_answer; //密碼答案

privatestring_s_question; //密碼問題

privateint_s_type; //用戶類型

privatestring_s_photo; //用戶圖片

privateint?_s_adminid;

//<summary>

//用戶ID

//</summary>

publicints_id

{

set{_s_id=value;}

get{return_s_id;}

}

//<summary>

//用戶名稱

//</summary>

publicstrings_name

{

set{_s_name=value;}

get{return_s_name;}

}

//<summary>

//用戶密碼

//</summary>

publicstrings_password

{

set{_s_password=value;}

get{return_s_password;}

}

//<summary>

//用戶QQ

//</summary>

publicstrings_qq

{

set{_s_qq=value;}

get{return_s_qq;}

}

//<summary>

//Email

//</summary>

publicstrings_email

{

set{_s_email=value;}

get{return_s_email;}

}

//<summary>

//聯(lián)系電話

//</summary>

publicstrings_phone

{

set{_s_phone=value;}

get{return_s_phone;}

}

//<summary>

//通信地址

//</summary>

publicstrings_address

{

set{_s_address=value;}

get{return_s_address;}

}

//<summary>

//性別

//</summary>

publicstrings_sex

{

set{_s_sex=value;}

get{return_s_sex;}

}

//<summary>

//身份證號

//</summary>

publicstrings_idcard

{

set{_s_idcard=value;}

get{return_s_idcard;}

}

//<summary>

//出生日期

//</summary>

publicDateTimes_date//這里的?表示該屬性可以為空

{

set{_s_date=value;}

get{return_s_date;}

}

//<summary>

//密碼答案

//</summary>

publicstrings_answer

{

set{_s_answer=value;}

get{return_s_answer;}

}

//<summary>

//密碼問題

//</summary>

publicstrings_question

{

set{_s_question=value;}

get{return_s_question;}

}

//<summary>

//用戶類型

//</summary>

publicint?s_type

{

set{_s_type=value;}

get{return_s_type;}

}

//<summary>

//用戶圖片

//</summary>

publicstrings_photo

{

set{_s_photo=value;}

get{return_s_photo;}

}

//<summary>

//

//</summary>

publicint?s_adminid

{

set{_s_adminid=value;}

get{return_s_adminid;}

}

#endregionModel

}

}9.2.3數(shù)據(jù)訪問層實現(xiàn)

當用戶注冊時,會向Users表插入一條記錄。在本系統(tǒng)中,數(shù)據(jù)訪問層(IDAL,DataAccessLayer)的實現(xiàn)分成以下三個步驟:

·定義對象接口類。

·實現(xiàn)數(shù)據(jù)訪問接口類。

·定義數(shù)據(jù)工廠類創(chuàng)建對象接口。

1.定義對象接口類

在解決方案中創(chuàng)建文件夾“IDAL”,并定義此文件夾下命名空間為“NetShop.IDAL”、名為IUsers的接口。這樣做是為了讓數(shù)據(jù)訪問層易于替換并支持其他數(shù)據(jù)庫,使用接口來強制自己實現(xiàn)整個數(shù)據(jù)訪問類的結構。代碼如下:

usingSystem;

usingSystem.Data;

namespaceNetShop.IDAL

{

//<summary>

//接口層IUsers的摘要說明

//</summary>

publicinterfaceIUsers

{

#region成員方法

//<summary>

//得到最大ID

//</summary>

intGetMaxId();

//<summary>

//是否存在該記錄

//</summary>

boolExists(ints_id);

//<summary>

//增加一條數(shù)據(jù)

//</summary>

intAdd(NetShop.Model.Usersmodel);

//<summary>

//更新一條數(shù)據(jù)

//</summary>

boolUpdate(NetShop.Model.Usersmodel);

//<summary>

//刪除一條數(shù)據(jù)

//</summary>

boolDelete(ints_id);

//<summary>

//得到一個對象實體

//</summary>

NetShop.Model.UsersGetModel(ints_id);

//<summary>

//獲得數(shù)據(jù)列表

//</summary>

DataSetGetList(stringstrWhere);

//<summary>

//獲得前幾行數(shù)據(jù)

//</summary>

DataSetGetList(intTop,stringstrWhere,stringfiledOrder);

//<summary>

//獲得數(shù)據(jù)列表

//</summary>

intGetUser(stringstrWhere);

//<summary>

//修改基本信息

//</summary>

//<paramname="model"></param>

//<returns></returns>

boolUpdatajiben(NetShop.Model.Usersmodel);

//<summary>

//修改問題答案

//</summary>

//<paramname="model"></param>

//<returns></returns>

boolUpdataQuestion(NetShop.Model.Usersmodel);

//<summary>

//修改密碼

//</summary>

//<paramname="model"></param>

//<returns></returns>

boolUpdatapassword(NetShop.Model.Usersmodel);

#endregion成員方法

}

}從上述代碼上看,接口沒有任何實現(xiàn)代碼,它的根本目的在于讓我們知道實現(xiàn)它的類應該具有的結構。這種方式對問題的理解更加直觀,但是在業(yè)務邏輯層上要求能夠訪問接口實現(xiàn)類中的所有方法。要實現(xiàn)這個目的,可以根據(jù)web.config文件中的配置,結合反射來加載數(shù)據(jù)訪問類并將其緩存。在數(shù)據(jù)工廠中,DataAccess類中CreateUsers的靜態(tài)方法實現(xiàn)了這個功能。

2.實現(xiàn)數(shù)據(jù)訪問接口類

在解決方案中,創(chuàng)建名為“SQLServerDAL”的文件夾,命名空間名為NetShop.SQLServerDAL,在此中建立名為“Users.cs”的類,實現(xiàn)IUsers接口。代碼如下:

usingSystem;

usingSystem.Data;

usingSystem.Text;

usingSystem.Data.SqlClient;

usingNetShop.IDAL;

usingNetShop.DBUtility;//請先添加引用

namespaceNetShop.SQLServerDAL

{

//<summary>

//數(shù)據(jù)訪問類Users

//</summary>

publicclassUsers:IUsers

{

publicUsers(){}

#region成員方法

//<summary>

//增加一條數(shù)據(jù)

//</summary>

publicintAdd(NetShop.Model.Usersmodel)

{

StringBuilderstrSql=newStringBuilder();

strSql.Append("insertintoNetShop_Users(");

strSql.Append("s_name,s_password,s_qq,s_email,s_phone,s_address,

s_sex,s_idcard,s_date,s_answer,s_question,s_type,s_photo,s_adminid)");

strSql.Append("values(");

strSql.Append("@s_name,@s_password,@s_qq,@s_email,@s_phone,

@s_address,@s_sex,@s_idcard,@s_date,@s_answer,@s_question,@s_type,

@s_photo,@s_adminid)");

strSql.Append(";select@@IDENTITY");

SqlParameter[]parameters={

newSqlParameter("@s_name",SqlDbType.VarChar,16),

newSqlParameter("@s_password",SqlDbType.VarChar,24),

newSqlParameter("@s_qq",SqlDbType.VarChar,12),

newSqlParameter("@s_email",SqlDbType.VarChar,30),

newSqlParameter("@s_phone",SqlDbType.VarChar,15),

newSqlParameter("@s_address",SqlDbType.VarChar,100),

newSqlParameter("@s_sex",SqlDbType.VarChar,2),

newSqlParameter("@s_idcard",SqlDbType.VarChar,20),

newSqlParameter("@s_date",SqlDbType.DateTime),

newSqlParameter("@s_answer",SqlDbType.VarChar,100),

newSqlParameter("@s_question",SqlDbType.VarChar,100),

newSqlParameter("@s_type",SqlDbType.Int,4),

newSqlParameter("@s_photo",SqlDbType.VarChar,100),

newSqlParameter("@s_adminid",SqlDbType.Int,4)};

parameters[0].Value=model.s_name;

parameters[1].Value=model.s_password;

parameters[2].Value=model.s_qq;

parameters[3].Value=model.s_email;

parameters[4].Value=model.s_phone;

parameters[5].Value=model.s_address;

parameters[6].Value=model.s_sex;

parameters[7].Value=model.s_idcard;

parameters[8].Value=model.s_date;

parameters[9].Value=model.s_answer;

parameters[10].Value=model.s_question;

parameters[11].Value=model.s_type;

parameters[12].Value=model.s_photo;

parameters[13].Value=model.s_adminid;

objectobj=DbHelperSQL.GetSingle(strSql.ToString(),parameters);

if(obj==null)

{

return1;

}

else

{

returnConvert.ToInt32(obj);

}

}

}

3.定義數(shù)據(jù)工廠類創(chuàng)建對象接口

在解決方案中,創(chuàng)建名為“DALFactory”的文件夾,命名空間名為NetShop.DALFactory,在此中建立名為“DataAccess.cs”的類來定義數(shù)據(jù)工廠,以實現(xiàn)數(shù)據(jù)訪問。代碼如下:

usingSystem;

usingSystem.Reflection;

usingSystem.Configuration;

namespaceNetShop.DALFactory

{

//<summary>

//AbstractFactorypatterntocreatetheDAL

//</summary>

publicsealedclassDataAccess

{

privatestaticreadonlystringAssemblyPath=ConfigurationManager.AppSettings["DAL"];

//<summary>

//創(chuàng)建Users數(shù)據(jù)層接口

//</summary>

publicstaticNetShop.IDAL.IUsersCreateUsers()

{

stringClassNamespace=AssemblyPath+".Users";

objectobjType=CreateObject(AssemblyPath,ClassNamespace);

return(NetShop.IDAL.IUsers)objType;

}

}

}9.2.4業(yè)務邏輯層實現(xiàn)

為了實現(xiàn)對用戶注冊信息的插入,業(yè)務邏輯層(BLL,BusinessLogicLayer)需要調(diào)用來自數(shù)據(jù)訪問層的方法,并將相關值作為參數(shù)傳遞給它。BLL命名空間下的USers類中的Add方法實現(xiàn)了這一過程。代碼如下所示:

usingNetShop.IDAL;

usingNetShop.DBUtility;

usingSystem.Text;

namespaceNetShop.BLL

{

//<summary>

//業(yè)務邏輯類Users的摘要說明

//</summary>

publicclassUsers

{

//定義訪問用戶對象的接口變量IUsers

privatereadonlyIUsersdal=DataAccess.CreateUsers();

publicUsers()

{}

#region成員方法

//<summary>

//增加一條數(shù)據(jù)

//</summary>

publicintAdd(NetShop.Model.Usersmodel)

{

returndal.Add(model);

}

}

}

這個方法完成了許多完全適合于業(yè)務邏輯層,并且不希望留給用戶界面層或數(shù)據(jù)訪問層的工作。9.2.5用戶接口層實現(xiàn)

通過對業(yè)務邏輯進行封裝后,用戶接口層(UI,UserInterface)的設計就主要在頁面設計和參數(shù)的傳遞了。用戶接口層上可以在不知道應用程序其他部分細節(jié)的情況下調(diào)用業(yè)務邏輯層的方法來實現(xiàn)相應的業(yè)務邏輯,達到應用層和業(yè)務邏輯層的協(xié)同工作。其部分代碼

如下:

publicpartialclassUiControl_user_add:System.Web.UI.UserControl

{

NetShop.BLL.Usersus=newNetShop.BLL.Users();

NetShop.Model.Usersuser=newNetShop.Model.Users();

stringimage="UpFiles/UserImages/none.gif";

protectedvoidBtnSubmit_Click(objectsender,EventArgse)

{

if(upImage())

{

user.s_name=tb_user_nam.Text.Trim();

user.s_password=Util.getpwd(tb_password.Text.Trim().ToString());

user.s_qq=tb_password.Text.Trim();

user.s_email=tb_email.Text.Trim();

user.s_phone=tb_phto.Text.Trim();

user.s_address=tb_adrees.Text.Trim();

user.s_sex=tb_sex.SelectedValue.ToString();

user.s_idcard=tb_user_id.Text.Trim();

user.s_date=DateTime.Now;

user.s_photo=image;

if(us.Add(user)>0)

JavaScript.alert("注冊成功");

else

JavaScript.alert("注冊失敗");

}

else

{

JavaScript.alert("頭像上傳失敗");

}

}

privateboolupImage()

{

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論