我們要進行分層了。是不是很緊張呢。先在這裏吹一吹三層結構是哪三層吧。
在軟件體系架構設計中,分層式結構是最常見,也是最重要的一種結構。微軟推薦的分層式結構一般分爲三層,從下至上分別爲:數據訪問層、業務邏輯層(又或稱爲領域層)、表示層,如圖所示:
數據訪問層:有時候也稱爲是持久層,其功能主要是負責數據庫的訪問。簡單的說法就是現對數據表的 Select,Insert,Update,Delete 的操作。
業務邏輯層:是整個系統的核心,它與這個系統的業務(領域)有關。如果涉及到數據庫的訪問,則調用數據訪問層。
表示層:是系統的 UI 部分,負責使用者與整個系統的交互。在這一層中,理想的狀態是不應包括系統的業務邏輯。表示層中的邏輯代碼,僅與界面元素有關。
微軟那麼牛B都說分三層了,我們就聽他的吧。給人家個面子嘛。蓋茨哥長的那麼帥
分層設計有什麼好處呢。
概括來說,分層式設計可以達至如下目的:分散關注、鬆散耦合、邏輯複用、標準定義。
我們先看頭兩個。
一個好的分層式結構,可以使得開發人員的分工更加明確。一旦定義好各層次之間的接口,負責不同邏輯設計的開發人員就可以分散關注,齊頭並進。例如 UI人員只需考慮用戶界面的體驗與操作,領域的設計人員可以僅關注業務邏輯的設計,而數據庫設計人員也不必爲繁瑣的用戶交互而頭疼了。每個開發人員的任務得到了確認,開發速度就可以迅速的提高。
一個東西,你把他分成幾個部分,大家每個人做一部分,速度自然就快咯。
鬆散耦合的好處是顯而易見的。如果一個系統沒有分層,那麼各自的邏輯都緊緊糾纏在一起,彼此間相互依賴,誰都是不可替換的。一旦發生改變,則牽一髮而動全身,對項目的影響極爲嚴重。降低層與層間的依賴性,可以良好地保證未來的可擴展。
現在我們開始擴展我們的StudentMIS。
分三層。分別是DAL(Data Access Layer,即數據訪問層),BLL(Business Logic Layer,即業務邏輯層),UI(User Interface,即用戶接口層)。
右擊解決方案->添加新項目。如圖所示:
選擇類庫,並將名稱設置爲BLL。
用相同的方法建立DAL。
在DAL和BLL中將自動生成的class1.cs刪除。各自添加一個新類User.cs,如圖:
由於各個層次之間存在調用關係。要對某個層次進行調用,必須在引用中添加要調用的層次。
在UI中我們對BLL進行調用。所以要在引用中添加BLL。
鼠標右擊Web項目,如圖:
在彈出的菜單中選擇添加引用。然後會彈出一個對話框,如圖:
選擇項目,然後選擇BLL。點擊確定。這樣就完成了對BLL項目的引用了。之後就可以通過在代碼開始添加using BLL;來使用BLL中的方法了。
使用相同的方法,在BLL項目中添加對DAL項目的引用。
下面是代碼內容。
BLL中的User.cs:
using DAL;
namespace BLL
{
public class User
{
DAL.User user = new DAL.User();
/// <summary>
/// 根據用戶Id獲取用戶密碼
/// </summary>
/// <param name="userId">用戶Id</param>
/// <returns>用戶密碼</returns>
public string GetUserPassword(string userId)
{
return user.GetUserPassword(userId);
}
/// <summary>
/// 根據用戶Id獲取用戶姓名
/// </summary>
/// <param name="userId">用戶Id</param>
/// <returns>用戶姓名</returns>
public string GetUserName(string userId)
{
return user.GetUserName(userId);
}
}
}
DAL中的User.cs
using System;
using System.Data.SqlClient;
namespace DAL
{
public class User
{
/// <summary>
/// 根據用戶Id獲取用戶密碼
/// </summary>
/// <param name="userId">用戶Id</param>
/// <returns>用戶密碼</returns>
public string GetUserPassword(string userId)
{
SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=StudentMIS;Integrated Security=True");//新建連接
SqlCommand cmd = new SqlCommand("select password from [User] where UserId=" + userId, conn);//新建命令,根據文本框tbxUserId中的值查詢數據庫中相應記錄的Password值
conn.Open();//打開連接
Object obj = cmd.ExecuteScalar();//執行語句,返回第一行第一列結果
conn.Close();//關閉連接
if (obj != null) return obj.ToString();//若查詢結果不爲空,則將其轉換爲字符串
else return null;//否則返回null
}
/// <summary>
/// 根據用戶Id獲取用戶姓名
/// </summary>
/// <param name="userId">用戶Id</param>
/// <returns>用戶姓名</returns>
public string GetUserName(string userId)
{
SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=StudentMIS;Integrated Security=True");//新建連接
SqlCommand cmd = new SqlCommand("select UserName from [User] where UserId=" + userId, conn);//新建命令,根據請求的UserId中的值查詢數據庫中相應記錄的UserName值
conn.Open();//打開連接
Object obj = cmd.ExecuteScalar();//執行語句,返回第一行第一列結果
conn.Close();//關閉連接
if (obj != null) return obj.ToString();//若查詢結果不爲空,則將其轉換爲字符串
else return null;//否則返回null
}
}
}
Login.aspx.cs:
using System;
using BLL;
public partial class Login : System.Web.UI.Page
{
User user = new User();//實例化BLL中的User類
protected void btnLogin_Click(object sender, EventArgs e)
{
if (tbxUserId.Text.Length == 0 || tbxPassword.Text.Length == 0) return;//若賬號密碼爲空,則返回
if (user.GetUserPassword(tbxUserId.Text)== tbxPassword.Text)//若查詢結果不爲空且與文本框tbxPassword中的值相等
Response.Redirect("Index.aspx?UserId="+tbxUserId.Text);//跳轉到Index.aspx
else
{
tbxUserId.Text = "";//清空tbxUserId中的值
tbxPassword.Text = "";//清空tbxPassword中的值
}
}
}
Index.aspx.cs:
using System;
using BLL;
public partial class Index : System.Web.UI.Page
{
User user = new User();//實例化BLL中的User類
public string UserName;//用戶名
protected void Page_Load(object sender, EventArgs e)
{
UserName = user.GetUserName(Request["UserId"]);//設置顯示的用戶名
}
}
這樣運行起來還是跟上一篇博文中的效果一樣。但是已經明確了分工。這樣,開發人員各搞各的,只要能確定對方的接口,到時候就可以進行組裝。
爲什麼本篇要叫三層肚皮呢。因爲肚皮裏油水太多了。看看我們的DAL,充斥着數據庫操作代碼。看起來暈暈的。不利於維護。代碼的可重用性差。
如何在三層結構中做好代碼複用的工作呢。請看下一篇博文:ASP.NET三層結構演化構建之三——用了又用
項目示例下載:http://download.csdn.net/source/2946951