ASP.NET的三層架構(DAL,BLL,UI)

BLL   是業務邏輯層   Business   Logic   Layer   

DAL   是數據訪問層   Data   Access   Layer          

ASP.NET的三層架構(DAL,BLL,UI)

 圖形表示三層結構. 其中web即爲USL層

web –> bll –> dal
|            |               |
|           V             |
+–> model <—+
一、三層體系架構
  1.表示層(USL):主要表示WEB方式,也可以表示成WINFORM方式。如果邏輯層相當強大和完善,無論表現層如何定義和更改,邏輯層都能完善地提供服務。
  2.業務邏輯層(BLL):主要是針對具體的問題的操作,也可以理解成對數據層的操作,對數據業務邏輯處理。如果說數據層是積木,那邏輯層就是對這些積木的搭建。
  3.數據訪問層(DAL):主要是對原始數據(數據庫或者文本文件等存放數據的形式)的操作層,而不是指原始數據,也就是說,是對數據的操作,而不是數據庫,具體爲業務邏輯層或表示層提供數據服務.


二、具體區分
  1.表示層:主要對用戶的請求接受,以及數據的返回,爲客戶端提供應用程序的訪問。
  2.業務邏輯層:主要負責對數據層的操作,也就是說把一些數據層的操作進行組合。
  3.數據訪問層:主要看你的數據層裏面有沒有包含邏輯處理,實際上他的各個函數主要完成各個對數據文件的操作,而不必管其他操作。


三、總結
  三層結構是一種嚴格分層方法,即數據訪問層(DAL)只能被業務邏輯層(BLL)訪問,業務邏輯層只能被表示層(USL)訪問,用戶通過表示層將請求傳送給業務邏輯層,業務邏輯層完成相關業務規則和邏輯,並通過數據訪問層訪問數據庫獲得數據,然後按照相反的順序依次返回將數據顯示在表示層。有的三層結構還加了Factory、Model等其他層,實際都是在這三層基礎上的一種擴展和應用.


一個簡單的三層結構程序一般包括DAL BLL WEB Model幾個項目,它們的相互引用關係如下:
1) WEB引用 BLL,Model
2)BLL引用 DAL,Model
3)DAL引用Model
4)Model無引用


 一提三層架構,大家都知道是表現層(UI),業務邏輯層(BLL)和數據訪問層(DAL),而且每層如何細分也都有很多的方法。但具體代碼怎麼寫,到底那些文件算在哪一層,卻是模模糊糊的。下面用一個簡單的例子來帶領大家實戰三層架構的項目,這個例子只有一個功能,就是用戶的簡單管理。 


     首先建立一個空白解決方案,添加如下項目及文件 
     1、添加ASP.NET Web Application項目,命名爲UI,新建Web Form類型文件User.aspx(含User.aspx.cs) 
     2、添加ClassLibrary項目,命名爲BLL,新建Class類型文件UserBLL.cs 
     3、添加ClassLibrary項目,命名爲DAL,新建Class類型文件UserDAL.cs。添加SQLHelper引用。(這個是微軟的數據訪問類,也可以不用,直接編寫所有的數據訪問代碼。我一般用自己寫的數據訪問類DataAccessHelper )。 
     4、添加ClassLibrary項目,命名爲Model,新建Class類型文件UserModel.cs 
     5、添加ClassLibrary項目,命名爲IDAL,新建Interface類型文件IUserDAL.cs 
     6、添加ClassLibrary項目,命名爲ClassFactory 
     相信大家已經看出來了,這個和Petshop的示例沒什麼區別,而且更簡單,因爲在下也是通過Petshop學習三層架構的。但一些朋友對於這幾個項目所處的層次,以及它們之間的關係,可能比較模糊,這裏逐個說明一下: 
     1、User.aspx和User.aspx.cs 
     這兩個文件(以及文件所屬的項目,下面也是如此,不再重複強調了)都屬於表現層部分。User.aspx比較好理解,因爲它就是顯示頁面了。User.aspx.cs有些人覺得不應該算,而是要劃到業務邏輯層中去。如果不做分層的話,那麼讓User.aspx.cs來處理業務邏輯,甚至操作數據庫都沒什麼問題,但是做分層的話,這樣就不應該了。在分層結構中,User.aspx.cs僅應該處理與顯示有關的內容,其它部分都不應該涉及。 
     舉例:我們實現用列表方式顯示用戶的功能,那麼提取信息的工作是由BLL來做的,UI(本例中是User.aspx.cs)調用BLL得到UserInfo後,通過代碼綁定到User.aspx的數據控件上,就實現了列表的顯示。在此過程中User.aspx.cs對UI沒有起到什麼作用,僅是用來傳遞數據,而且因爲實際編碼中大部分情況都是如此的實現,所以使有些人覺得User.aspx.cs不應該算UI,而應該併入BLL負責邏輯處理。繼續往下看,這時提出了一個新需求,要求在每個用戶的前面加一個圖標,生動地表現出用戶的性別,而且不滿18歲的用兒童圖標表示。這個需求的實現,就輪到User.aspx.cs來做了,這種情況下User.aspx.cs纔算有了真正的用途。 
     2、NewBLL.cs 
     添加如下方法: 
     public IList GetUsers():返回所有的用戶信息列表 
     public UserInfo GetUser(int UserId):返回指定用戶的詳細信息 
     public bool AddUser(UserInfo User):新增用戶信息 
     public bool ChangeUser(UserInfo User):更新用戶信息 

     public void RemoveUser(int UserId):移除用戶信息 


     此文件就屬於業務邏輯層了,專門用來處理與業務邏輯有關的操作。可能有很多人覺得這一層唯一的用途,就是把表現層傳過來的數據轉發給數據層。這種情況確實很多,但這隻能說明項目比較簡單,或者項目本身與業務的關係結合的不緊密(比如當前比較流行的MIS),所以造成業務層無事可做,只起到了一個轉發的作用。但這不代表業務層可有可無,隨着項目的增大,或者業務關係比較多,業務層就會體現出它的作用來了。 
     此處最可能造成錯誤的,就是把數據操作代碼劃在了業務邏輯層,而把數據庫作爲了數據訪問層。 
     舉例:有些朋友感覺BLL層意義不大,只是將DAL的數據提上來就轉發給了UI,而未作任何處理。看一下這個例子 
     BLL層 
     SelectUser(UserInfo userInfo)根據傳入的username或email得到用戶詳細信息。 
     IsExist(UserInfo userInfo)判斷指定的username或email是否存在。 
     然後DAL也相應提供方法共BLL調用 
     SelectUser(UserInfo userInfo) 
     IsExist(UserInfo userInfo) 
     這樣BLL確實只起到了一個傳遞的作用。 
     但如果這樣做: 
     BLL.IsExist(Userinfo userinfo) 
     { 
         UerInfo user = DAL.SelectUser(User); 
         return (userInfo.Id != null); 
     } 
     那麼DAL就無需實現IsExist()方法了,BLL中也就有了邏輯處理的代碼。 
     3、UserModel.cs 
     實體類,這個東西,大家可能覺得不好分層。包括我以前在內,是這樣理解的:UI?àModel?àBLL?àModel?àDAL,如此則認爲Model在各層之間起到了一個數據傳輸的橋樑作用。不過在這裏,我們不是把事情想簡單,而是想複雜了。 
     Model是什麼?它什麼也不是!它在三層架構中是可有可無的。它其實就是面向對象編程中最基本的東西:類。一個桌子是一個類,一條新聞也是一個類,int、string、doublie等也是類,它僅僅是一個類而已。 
     這樣,Model在三層架構中的位置,和int,string等變量的地位就一樣了,沒有其它的目的,僅用於數據的存儲而已,只不過它存儲的是複雜的數據。所以如果你的項目中對象都非常簡單,那麼不用Model而直接傳遞多個參數也能做成三層架構。 
     那爲什麼還要有Model呢,它的好處是什麼呢。下面是思考一個問題時想到的,插在這裏: 
     Model在各層參數傳遞時到底能起到做大的作用? 
     在各層間傳遞參數時,可以這樣: 
     AddUser(userId,userName,userPassword,…,) 
     也可以這樣: 
     AddUser(userInfo) 
     這兩種方法那個好呢。一目瞭然,肯定是第二種要好很多。 
     什麼時候用普通變量類型(int,string,guid,double)在各層之間傳遞參數,什麼使用Model傳遞?下面幾個方法: 
     SelectUser(int UserId) 
     SelectUserByName(string username) 
     SelectUserByName(string username,string password) 
     SelectUserByEmail(string email) 
     SelectUserByEmail(string email,string password) 
     可以概括爲: 
     SelectUser(userId) 
     SelectUser(user) 
     這裏用user這個Model對象囊括了username,password,email這三個參數的四種組合模式。UserId其實也可以合併到user中,但項目中其它BLL都實現了帶有id參數的接口,所以這裏也保留這一項。 
     傳入了userInfo,那如何處理呢,這個就需要按照先後的順序了,有具體代碼決定。 
     這裏按這個順序處理 
     首先看是否同時具有username和password,然後看是否同時具有email和password,然後看是否有username,然後看是否有email。依次處理。 
     這樣,如果以後增加一個新內容,會員卡(number),則無需更改接口,只要在DAL的代碼中增加對number的支持就行,然後前臺增加會員卡一項內容的表現與處理即可。 
     4、UserDAL.cs 
     public IList SelectUsers():返回所有的用戶信息列表 
     public UserInfo SelectUser(int UserId):返回指定用戶的相信信息 
     public bool InsertUser(UserInfo User):新增用戶信息 
     public bool UpdateUser(UserInfo User):更新用戶信息 
     public void DeleteUser(int UserId):移除用戶信息 
     很多人最鬧不清的就是數據訪問層,到底那部分纔算數據訪問層呢?有些認爲數據庫就是數據訪問層,這是對定義沒有搞清楚,DAL是數據訪問層而不是數據存儲層,因此數據庫不可能是這一層的。也有的把SQLHelper(或其同類作用的組件)作爲數據訪問層,它又是一個可有可無的東西,SQLHelper的作用是減少重複性編碼,提高編碼效率,因此如果我習慣在乎效率或使用一個非數據庫的數據源時,可以丟棄SQLHelper,一個可以隨意棄置的部分,又怎麼能成爲三層架構中的一層呢。 
     可以這樣定義:與數據源操作有關的代碼,就應該放在數據訪問層中,屬於數據訪問層 
     5、IUserDAL 
     數據訪問層接口,這又是一個可有可無的東西,因爲Petshop中帶了它和ClassFactory類工廠,所以有些項目不論需不需要支持多數據源,都把這兩個東西做了進來,有的甚至不建ClassFactory而只建了IDAL,然後“IUserDAL iUserDal = new UserDAL();”,不知意義何在。這就完全是畫虎不成反類犬了。 
     許多人在這裏有一個誤解,那就是以爲存在這樣的關係:BLL?àIDAL?àDAL,認爲IDAL起到了BLL和DAL之間的橋樑作用,BLL是通過IDAL來調用DAL的。但實際是即使你如此編碼:“IUserDAL iUserDal = ClassFacotry.CreateUserDAL();”,那麼在執行“iUserDal.SelectUsers()”時,其實還是執行的UserDAL實例,而不是IUserDAL實例,所以IDAL在三層中的位置是與DAL平級的關係。 
     通過上面的介紹,基本上將三層架構的層次結構說明了。其實,本人有一個判斷三層架構是否標準的方法,那就是將三層中的任意一層完全替換,都不會對其它兩層造成影響,這樣的構造基本就符合三層標準了(雖然實現起來比較難^_^)。例如如果將項目從B/S改爲C/S(或相反),那麼除了UI以外,BLL與DAL都不用改動;或者將SQLServer改爲Oracle,只需替換SQLServerDAL到OracleDAL,無需其它操作等等。本來想在文中加入一些具體的代碼的,但感覺不是很必要,如果大家覺得需要的話,我再補充吧。 
     總結:不要因爲某個層對你來說沒用,或者實現起來特別簡單,就認爲它沒有必要,或者摒棄它,或者挪作它用。只要進行了分層,不管是幾層,每一層都要有明確的目的和功能實現,而不要被實際過程所左右,造成同一類文件位於不同層的情況發生。也不要出現同一層實現了不同的功能的情況發生。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章