一:三層構架的基礎知識
在項目開發的過程中,有時把整個項目分為三層架構,其中包括:表示層(UI)、業務邏輯層(BLL)和數據訪
問層(DAL)。三層的作用分別如下:
表示層:
為用戶提供交互操作界面,這一點不論是對於Web還是WinForm都是如此,就是用戶界面操作
。我們網站展示給用戶看的界面。
業務邏輯層:
負責關鍵業務的處理和數據的傳遞。復雜的邏輯判斷和涉及到數據庫的數據驗證都需要在此
做出處理。根據傳入的值返回用戶想得到的值,或者處理相關的邏輯。
數據訪問層:
見名知意,負責數據庫數據的訪問。主要為業務邏輯層提供數據,根據傳入的值來操作數據
庫,增、刪、改或者其它。
以下我簡單介紹下一個用戶管理模塊:
為了整個項目的開發方便,我們在項目中會建幾個類庫Common,BLL,DAL,Model。
為了命名清晰,我們可以這樣命名這個三個工程(即在解決方案里添加的類庫):
業務邏輯層(BusinessLogicLayer):BLL,命名空間默認設置為BLL
數據訪問層(DataAccessLayer):DAL,命名空間默認設置為DAL
工具類:如:Common,命名空間默認設置為Common
另外我們為了數據傳遞的方便,通常再添加一個類庫,這個類庫是貫穿於整個三層架構中的。即實體類。
通常命名為Model,命名空間默認值設置為:Models。其中封裝的每個類都對應一個實體,通常就是數據庫
中的一個表。如數據庫中的用戶表(custom)封裝為(custom),將表中的每個字段都封裝成共有的屬
性。
這樣三層架構的搭建就基本完成了。這三層有着非常強的依賴關系:
表示層 ← 業務邏輯層 ← 數據訪問層
他們之間的數據傳遞是雙向的,並且通常借助實體類傳遞數據。
那么三層架構都有哪些優點呢:
1、易於項目的修改和維護。
在項目的開發過程中或者開發后的升級過程中,甚至在項目的移植過程中。
這種三層架構是非常方便的。比如項目從Web移植到Form,我們只需要將表示層重新做一遍就可以了。
其余兩層不用改動,只需添加到現有項目就可以了。如果不采用這種架構,只是將代碼寫到表示層。那么
所有的編碼幾乎都要重新來了。
2、易於擴展。
在功能的擴展上同樣如此,如有功能的添加只需把原有的類庫添加方法就可了
3、易於代碼的重用。
這一點就不用解釋了。
4、易於分工協作開
還可以加個接口類庫Iinterface, 加入設計模式,使你的代碼靈活性更好,質量更高。
二:系統登錄的例子
a,整體
b,OperationLogBLL.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using HRMSys.DAL; namespace HRMSys.BLL { /// <summary> /// 插入操作記錄 /// </summary> public class OperationLogBLL { OperationLogDAL dal = new OperationLogDAL(); public void InsertOperationLog(Guid id, string name, string ActionDesc) { dal.InsertLog(id, name, ActionDesc); } } }
c,OperatorBLL.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using HRMSys.DAL; using HRMSys.Model; using Common; namespace HRMSys.BLL.cs { public class OperatorBLL { OperatorDAL dal=new OperatorDAL(); /// <summary> /// 得到指定name的operator的數據 /// </summary> /// <param name="name"></param> /// <returns></returns> public Operator getOperatorByName(string name) { Operator op=new Operator(); op=dal.loginUser(name); return op; } /// <summary> /// 密碼錯誤超過三次,鎖定登錄者 /// </summary> /// <param name="op"></param> public void updateOperator(Operator op) { dal.UpdateOperator(op); } /// <summary> /// 登錄 /// </summary> /// <returns></returns> public bool login(string name,int errorTime,string pwd,out string message,out Operator op) { bool r = false; if (name.Length <= 0) { message = "請輸入用戶名"; op = null; return r; } if (pwd.Length <= 0) { message = "請輸入用戶名"; op = null; return r; } if (errorTime>=3) { message = "用戶已被鎖定"; op = null; return r; } else { op = dal.loginUser(name); if (op == null) { message = "用戶名不存在"; } else { pwd = CommonHelper.GetMD5(pwd + CommonHelper.getPasswordSalt()); if (op.Password != pwd) { message = "密碼不正確"; op.IsLocked = true; updateOperator(op); return r; } else { if (op.IsLocked == true) message = "用戶被鎖定"; else { r = true; message = "登錄成功"; } } } return r; } } } }
d,OperationLogDAL.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using HRMSys.Model; using System.Data; using System.Data.SqlClient; namespace HRMSys.DAL { public class OperationLogDAL { /// <summary> /// 插入一條操作記錄 /// </summary> /// <param name="OperatorId"></param> /// <param name="ActionDesc"></param> public void InsertLog(Guid OperatorId, string loginUser, string ActionDesc) { sqlhelper.ExecuteNon(@"insert into T_OperationLog(Id,OperatorId,MakeDate,ActionDesc,LoginUser) values(newid(),@OperatorId,getdate(),@ActionDesc,@LoginUser)", new SqlParameter("@ActionDesc", ActionDesc), new SqlParameter("@OperatorId", OperatorId), new SqlParameter("@LoginUser", loginUser));//這里是values,不是value } } }
e,OperatorDAL.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using HRMSys.Model; using System.Data.SqlClient; using System.Data; namespace HRMSys.DAL { public class OperatorDAL { /// <summary> /// 將表的形式轉換為vs的形式,給對象 /// </summary> /// <param name="row"></param> /// <returns></returns> private Operator ToOperator(DataRow row) { Operator op = new Operator(); op.Id = (Guid)row["Id"];//不加就可以檢查用戶名是否重復了 op.UserName = (string)row["UserName"]; op.Password = (string)row["Password"]; op.IsLocked = (bool)row["IsLocked"]; op.IsDelete=(bool)row["IsDelete"]; op.RealName = (string)row["RealName"]; return op; } /// <summary> ///查詢指定username的一條數據 /// </summary> /// <param name="name"></param> /// <returns></returns> public Operator loginUser(string name) { DataTable table = sqlhelper.datatable("select * from T_Operator where UserName=@UserName and IsDelete=0 and IsLocked=0", new SqlParameter("@UserName", name)); if (table.Rows.Count <= 0) return null; else if (table.Rows.Count > 1) throw new Exception("用戶名重復"); else { DataRow row = table.Rows[0]; return ToOperator(row); } } /// <summary> /// 鎖定管理員更新管理員表 /// </summary> /// <param name="op"></param> public void UpdateOperator(Operator op) { sqlhelper.ExecuteNon("update T_Operator set IsLocked=@IsLocked where Id=@Id", new SqlParameter("@IsLocked", op.IsLocked), new SqlParameter("@id",op.Id)); } } }
f,login.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using HRMSys.Model; using HRMSys.BLL; using HRMSys.BLL.cs; namespace HYMSys.UI { public partial class login : Form { public login() { InitializeComponent(); } int errorTime = 0; string message; Operator op; OperationLogBLL logbll = new OperationLogBLL(); OperatorBLL bll = new OperatorBLL(); /// <summary> /// 登錄,並保存登錄操作記錄 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { //返回是否登錄成功的bool類型,並將提示信息和管理員對象返回 bool result= bll.login(tb_name.Text, errorTime, tb_pwd.Text, out message, out op); if (result == false) { errorTime += 1; MessageBox.Show(message); return; } else { //插入一條操作記錄 logbll.InsertOperationLog(op.Id, op.UserName, message); MessageBox.Show(message); } } /// <summary> /// 取消 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button2_Click(object sender, EventArgs e) { this.Close(); } } }
三:總結
這是一個非常簡單但非常典型的一個三層架構的小例子,希望能給像我一樣的初學者一些幫助。歡迎大家來積極的討論。