【C#】之七層登入程式碼詳解
前言
之前我有寫過一篇三層登入,應用三層,將介面處理、業務邏輯處理和資料訪問分別開來,能夠很好的減少登入系統中各個模組之間的耦合度,使的系統更加可維護、可複用和可擴充套件。而七層登入是在三層基礎之上的更完美的改進,他除了主三層中有的UI層、BLL層、DAL層和Enitity層(實體層)之外,還引入了Facade層(外觀層)、IDAL層(介面層)、Factory層(工廠層)和SQLHelper類,使得三層更加獨立封閉,充分體現了面向物件程式設計。下面我們就來具體看一下七層到底是怎樣實現的。
一、新增加的層?
1、 Facade層(外觀層)
外觀層應用了設計模式中的外觀模式
2、Factory層(工廠層)
工廠層應用了設計模式中的抽象工廠模式(提供一個建立一系列相關或相互依賴物件的介面,而無需指定他們具體的類)
3、IDAL層(介面層)
介面層的應用充分實現了介面隔離遠原則,它位於BLL層與DAL層之間,BLL層與DAL層中的類沒有必要直接通訊,當BLL層中的一個類需要呼叫DAL層中一個類的方法時,可以通過介面IDAL來轉發這個呼叫。
4、SQLHelper類
這一層沒有單獨的名稱空間,可以將它看做是DAL層中的一個輔助類
二、圖解
我們在分析的時候,是按照資料流動的情況進行分析的,即UI——>Facade——>BLL——>Factory——>IDAL——>DAL——>SQLHelper,但是資料是貫穿於整個七層的,為了避免敲程式碼是後所引用的方法爆紅(前提是現將類都建好並命好名),我們在敲程式碼的時候的順序與分析的順序不一致,即Enitity——》IDAL——》DAL——》Factory——》BLL——》Facade——》UI,這樣只是為了方便書寫,當然,如果敲起來不順手的話,還可以從頭向後敲,每用到一個方法就去寫一個方法框架。
三、程式碼詳解
按照我們分析的過程進行程式碼詳解。
Enitity層
namespace Enitity
{
//實體層
public class UserInfo
{
//定義使用者ID屬性
private int userid;
public int UserID
{
get { return userid; }
set { userid = value; }
}
//定義使用者密碼PassWord屬性
private string password;
public string PassWord
{
get { return password; }
set { password = value; }
}
}
UI層
private void BtnLogin_Click(object sender, EventArgs e)
{
//判斷輸入不能為空
if (TxtID.Text.Trim() == "")
{
MessageBox.Show("請輸入使用者名稱!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
if (TxtPassword.Text == "")
{
MessageBox.Show("請輸入密碼!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
try
{
//例項化一個使用者實體user
Enitity.UserInfo user = new Enitity.UserInfo();
//接收控制元件傳來的使用者資訊
user.UserID = Convert .ToInt32(TxtID.Text.Trim());
//接收控制元件傳來的密碼資訊
user.PassWord = TxtPassword.Text;
//例項化外觀
Facade.LoginFacade FLogin = new Facade.LoginFacade();
//定義一個bool型的變數,用來接收是否查詢成功
Boolean flag = false;
//呼叫外觀的方法,返回給flag
flag = FLogin.SelectUser(user);
//判斷是否登入成功
if (flag != false)
{
MessageBox.Show("登入成功!");
this.Hide();
this.DialogResult = System.Windows.Forms.DialogResult.OK;
//例項化一個窗體
Form a = new Form();
a.Show();
}
else
{
MessageBox.Show("使用者名稱或密碼錯誤!");
}
}
catch (Exception)
{
throw;
}
}
Facade層
namespace Facade
{
//外觀層
public class LoginFacade
{
//將資料user從UI層傳入BLL層,提供返回值給flag
public Boolean SelectUser(Enitity.UserInfo user )
{
bool flag;
//例項化一個B層
BLL.LoginBLL userBLL = new BLL.LoginBLL();
//將使用者資料傳入B層,返回值給flag
flag = userBLL.UserBLL(user);
return flag;
}
}
}
BLL層
namespace BLL
{
//業務邏輯層
public class LoginBLL
{
//判斷使用者是否存在
public bool UserBLL(Enitity.UserInfo user)
{
//例項化工廠
Factory.LoginFactory fact = new Factory.LoginFactory();
//呼叫工廠中的方法,例項化一個實現介面的內部類,將反射結果賦給idal
IDAL.LoginIDAL idal = fact.CreateUser();//登入中,此時的idal反射的是dal中的LoginDAL類
//接收D層的返回值
DataTable table = idal.SelectUser(user);
bool flag;
//返回資料表型別,如果行數=0,說明沒有符合該賬號密碼的使用者
if (table.Rows.Count ==0)
{
flag = false;
}
else
{
flag = true;
}
//返回數值
return flag;
}
}
}
Factory層
namespace Factory
{
//工廠層
public class LoginFactory
{
//接收來自配置檔案的資料,明確工廠要連結那一層
string StrDB = System.Configuration.ConfigurationManager.AppSettings["DB"];
//應用反射來獲取被呼叫的DAL層的具體操作類
public IDAL.LoginIDAL CreateUser()
{
//明確具體操作類
string ClassName = StrDB + "." + "LoginDAL";
//反射加工廠的應用——將在DAL層中用到的具體類反射到介面,說明那個類實現了這個介面
return (IDAL.LoginIDAL)Assembly.Load(StrDB).CreateInstance(ClassName);
}
}
}
IDAL層
namespace IDAL
{
public interface LoginIDAL
{
//放置介面函式,判斷要登入的使用者是否在資料表中存在
DataTable SelectUser(Enitity.UserInfo user);
}
}
DAL層
namespace DAL
{
public class LoginDAL:IDAL.LoginIDAL
{
public DataTable SelectUser(Enitity.UserInfo user)
{
//例項化資料操作類,進行資料查詢,並獲取返回值
SQLHelper sqlHelper = new SQLHelper();
//選擇要查詢的資料型別,作為sqlCommand的引數
SqlParameter[] sqlparams = {new SqlParameter ("@ID",user.UserID),
new SqlParameter("@Password",user.PassWord )};
//查詢語句
string sql = "select * from Users where ID [email protected] AND [email protected]";
//將查詢語句和要查詢的資料 傳入sqlHelper類中進行查詢操作
DataTable table = sqlHelper.ExecuteQuery(sql,sqlparams,CommandType.Text);//CommandType.Text解釋SQL文字命令的字串
return table;
}
}
}
SQLHelper類
namespace DAL
{
//資料訪問層——資料操作類
public class SQLHelper
{
private SqlConnection conn = null;//定義資料連線操作
private SqlCommand cmd = null; //指定能在資料庫上執行的操作
private SqlDataReader sdr = null; //定義一個讀取資料流的變數,從資料庫中只讀
/// <summary>
/// 資料庫連線
/// </summary>
public SQLHelper()//建構函式
{
string connStr = ConfigurationManager.AppSettings["connStr"];//ConnStr配置檔案中連線資料庫的關鍵字(字串)
conn = new SqlConnection(connStr); //例項化一個連線
}
//將連線的資料庫開啟
private SqlConnection GetConn()
{
if (conn.State == ConnectionState.Closed )//如果連線狀態為關閉,則開啟
{
conn.Open();
}
return conn;
}
//只顯示執行程式碼,SQLHelper類中的其他資料庫操作省略
/// <summary>
/// 執行帶引數的SQL查詢語句或儲存過程
/// </summary>
/// <param name="cmdText"></param>
/// <param name="paras"></param>
/// <param name="ct"></param>
/// <returns></returns>
public DataTable ExecuteQuery(string cmdText,SqlParameter[] paras,CommandType ct)
{
//例項化一個數據表
DataTable dt = new DataTable ();
//例項化出一個數據操作
cmd = new SqlCommand(cmdText, GetConn ());//cmdText為傳進來的SQL命令,GetConn為一個開啟狀態的資料庫連線
cmd.CommandType = ct;
cmd.Parameters .AddRange (paras);//將要查詢的資料放入查詢語句中
//cmd.ExecuteReader讀取結果集中的資料,將完整的資料傳送到connection,生成sqlDataReader賦給sdr。
//括號中表明當關閉sqlDataReader時,關聯的connection也會關閉。
using (sdr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
//通過提供的sqlDataReader,對錶進行操作
dt.Load(sdr);
}
return dt;
}
}
}
結:對於七層登入,一定要理清他的邏輯思路,層與層之間的關係以及程式碼的執行過程,敲完之後多跑幾遍,對於不懂得方法充分利用好ArcObjects幫助文件,裡面的解釋非常詳細(還要感謝帥行的幫助,萬分感謝!)