ASP.NET的三層架構(DAL,BLL,UI)數據庫
圖形表示三層結構. 其中web即爲USL層編程
web –> bll –> dal
| | |
| V |
+–> model <—+架構
1、三層體系架構
1.表示層(USL):主要表示WEB方式,也能夠表示成WINFORM方式。若是邏輯層至關強大和完善,不管表現層如何定義和更改,邏輯層都能完善地提供服務。
2.業務邏輯層(BLL):主要是針對具體的問題的操做,也能夠理解成對數據層的操做,對數據業務邏輯處理。若是說數據層是積木,那邏輯層就是對這些積木的搭建。
3.數據訪問層(DAL):主要是對原始數據(數據庫或者文本文件等存放數據的形式)的操做層,而不是指原始數據,也就是說,是對數據的操做,而不是數據庫,具體爲業務邏輯層或表示層 函數
提供數據服務.post
2、具體區分
1.表示層:主要對用戶的請求接受,以及數據的返回,爲客戶端提供應用程序的訪問。
2.業務邏輯層:主要負責對數據層的操做,也就是說把一些數據層的操做進行組合。
3.數據訪問層:主要看你的數據層裏面有沒有包含邏輯處理,實際上他的各個函數主要完成各個對數據文件的操做,而沒必要管其餘操做。學習
3、總結
三層結構是一種嚴格分層方法,即數據訪問層(DAL)只能被業務邏輯層(BLL)訪問,業務邏輯層只能被表示層(USL)訪問,用戶經過表示層將請求傳送給業務邏輯層,業務邏輯層完成相關業務規則和邏輯,並經過數據訪問層訪問數據庫得到數據,而後按照相反的順序依次返回將數據顯示在表示層。有的三層結構還加了Factory、Model等其餘層,實際都是在這三層基礎上的一種擴展和應用.ui
一個簡單的三層結構程序通常包括DAL BLL WEB Model幾個項目,它們的相互引用關係以下
1) WEB引用 BLL,Model
2)BLL引用 DAL,Model
3)DAL引用Model
4)Model無引用編碼
一提三層架構,你們都知道是表現層(UI),業務邏輯層(BLL)和數據訪問層(DAL),並且每層如何細分也都有不少的方法。但具體代碼怎麼寫,到底那些文件算在哪一層,倒是模模糊糊的。下面用一個簡單的例子來帶領你們實戰三層架構的項目,這個例子只有一個功能,就是用戶的簡單管理。
首先創建一個空白解決方案,添加以下項目及文件 一、添加ASP.NET Web Application項目,命名爲UI,新建Web Form類型文件User.aspx(含User.aspx.cs) 二、添加ClassLibrary項目,命名爲BLL,新建Class類型文件UserBLL.cs 三、添加ClassLibrary項目,命名爲DAL,新建Class類型文件UserDAL.cs。添加SQLHelper引用。(這個是微軟的數據訪問類,也能夠不用,直接編寫全部的數據訪問代碼。我通常用本身寫的數據訪問類DataAccessHelper )。 四、添加ClassLibrary項目,命名爲Model,新建Class類型文件UserModel.cs 五、添加ClassLibrary項目,命名爲IDAL,新建Interface類型文件IUserDAL.cs 六、添加ClassLibrary項目,命名爲ClassFactory 相信你們已經看出來了,這個和Petshop的示例沒什麼區別,並且更簡單,由於在下也是經過Petshop學習三層架構的。但一些朋友對於這幾個項目所處的層次,以及它們之間的關係,可能比較模糊,這裏逐個說明一下: 一、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纔算有了真正的用途。 二、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中也就有了邏輯處理的代碼。 三、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的支持就行,而後前臺增長會員卡一項內容的表現與處理便可。 四、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,一個能夠隨意棄置的部分,又怎麼能成爲三層架構中的一層呢。 能夠這樣定義:與數據源操做有關的代碼,就應該放在數據訪問層中,屬於數據訪問層 五、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,無需其它操做等等。原本想在文中加入一些具體的代碼的,但感受不是很必要,若是你們以爲須要的話,我再補充吧。 總結:不要由於某個層對你來講沒用,或者實現起來特別簡單,就認爲它沒有必要,或者摒棄它,或者挪做它用。只要進行了分層,無論是幾層,每一層都要有明確的目的和功能實現,而不要被實際過程所左右,形成同一類文件位於不一樣層的狀況發生。也不要出現同一層實現了不一樣的功能的狀況發生。