1. 程式人生 > >【C#】之三層登入

【C#】之三層登入

一、什麼是三層

  我們在進行軟體設計時,一個重要的思想就是“高內聚低耦合”,而以前我們所做的那些小專案,由於程式碼量少,結構簡單,所有的操作都是在客戶端和資料庫之間(也就是兩層架構)進行的,但是對於大型的專案而言,如果按照原來的兩層架構進行設計,非常不利於軟體的可維護、可複用和可擴充套件性,並且導致各個層之間的依賴緊密,不利於開發人員的開發,違背了高內聚低耦合的思想。

  所謂三層結構就是在客戶端和資料庫之間加了一箇中間層,也就是元件層,這裡三層指的是邏輯上的三層,即把三層放到同一臺機器上,它包括介面層(UI)、業務邏輯層(BLL)和資料訪問層否(DAL)。

二、什麼時候用三層

  當業務邏輯複雜到一定程度,資料儲存作為一個相對獨立的資料儲存介質的情況下,把資料訪問層脫離業務層單獨存在,業務邏輯脫離開介面層二單獨存在。

三、為什麼使用三層

  我們之前用兩層架構,將使用者介面控制業務邏輯和資料訪問放在一起作為一層,資料庫單獨作為一層,這樣一來,如果資料庫或使用者介面發生改變時,需要重新開發整個系統。

應用三層架構,實現了高內聚低耦合的思想,將使用者見面、業務邏輯、資料訪問分開,當資料庫或使用者介面發生改變時,不需要重新開發只做簡單的調整即可。

四、優缺點

優點

1、開發人員可以只關注整個結構中的其中某一層;
2、可以很容易的使用新的實現來替換原有的層次的實現
3、可以降低層與層之間的依賴
4、有利於標準化
5、有利於個邏輯層的複用
6、結構更加明確
7、在後期維護時,極大的降低了維護成本和維護時間

缺點

1、降低系統性能。由於增加了層,訪問資料庫時要多經歷了一步,所以效能效率有所降低。
2、有時候會導致級聯的修改。如果在表示層增加一個功能,可能需要在相應的業務邏輯層和資料訪問層中都增加相應的程式碼。
3、增加開發成本。

五、各層的作用

介面層(UI)

位於最外面,進行使用者介面設計,向用戶展現特定業務資料,提供互動介面,並且採集使用者的輸入資訊和操作。

資料訪問層(DAL)

只限於和資料來源打交道
實現資料的增、刪、改、查

業務邏輯層(BLL)

是DAL和UI之間的橋樑,負責資料的處理和傳遞。
從DAL中獲取資料,以供UI使用
從UI中獲取使用者指令和資料後執行業務邏輯
從UI中獲取使用者指令和資料後,通過DAL寫入資料來源

model層(實體層)

並不屬於三層中的任何一層,他的存在只是為了封裝資料,使資料能夠在三層之間順暢的流轉,內部與資料庫中的表一一對應。

在這裡插入圖片描述

六、三層登入實現

應用三層實現最簡單的登入功能。

介面層

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnLogin_Click(object sender, EventArgs e)
        {            
            //接收控制元件變數
            string userID = txtname.Text.Trim();
            string password = txtpassword.Text;

            //例項化出一個業務邏輯層mgr
            Login.BLL.LoginManager mgr = new Login.BLL.LoginManager();

            //傳入引數到業務邏輯層處理後,將處理好的資料封裝在model層中
            Login.Model.UserInfo user= mgr.UserLogin(userID, password);

            MessageBox.Show("登入使用者:" + user.ID);           
        }
    }

業務邏輯層

namespace Login.BLL
{
    public class LoginManager
    {
        public Login.Model .UserInfo   UserLogin(string userID,string Password)
        {

            //例項化資料訪問層的UserDAO類為udao
            Login.DAL.UserDAO udao = new Login.DAL.UserDAO();

            //傳入資料後,用user接收資料訪問後的結果
            Login.Model.UserInfo user= udao.SelectUser(userID, Password);

            //如果資料訪問結果不為空
            if (user !=null ) 
            {
                //例項化資料訪問層的ScoreDAO類為sDao
                Login.DAL.ScoreDAO sDao = new Login.DAL.ScoreDAO();
                //傳入資料
                sDao.UpdateScore(userID, 10);

                return user;

            }
            else
            {
                throw new Exception("登入失敗。");
            }
        }
        

    }
}

model層

namespace Login.Model
{
    public class UserInfo
    {
        //定義好user需要的屬性,
        public int ID { get; set; }
        public string UserName { get; set; }
        public string Passsword { get; set; }
        public string Email { get; set; }
            
    }
}

資料訪問層

namespace Login.DAL
{
    public class UserDAO
    {
        public  Login.Model .UserInfo  SelectUser (string userID,string password)
            //定義兩個引數,接收業務邏輯層傳來的資料
        {
            //例項出一個數據連線conn,using之後,連線自動關閉
            using (SqlConnection conn =new SqlConnection(DbUtil.ConnString))
            {
                //定義一個查詢語句
                SqlCommand cmd = conn.CreateCommand();
                //知識(@符號1、忽略轉義字元,像路徑中的\符號。2、讓字串跨行。3、識別符號用法,加上後可以使用關鍵字。本處為2
                cmd.CommandText = @"SELECT ID,UserName,Password,Email
                                    FROM USERS WHERE [email protected] AND [email protected]";

                //將UserID和password作為要查詢語句的條件,給cmd
                cmd.CommandType = System.Data.CommandType.Text;
                cmd.Parameters.Add(new SqlParameter("@userID", userID));
                cmd.Parameters.Add(new SqlParameter("@password", password));

                //開啟連線
                conn.Open();

                //執行查詢語句
                SqlDataReader reader = cmd.ExecuteReader();

                //初始化user屬性為空
                Login.Model.UserInfo user = null;

                while (reader.Read())
                {
                    if (user ==null)
                    {
                        //例項出一個model為user
                        user = new Login.Model.UserInfo();
                    }

                    //查詢後,為model賦值
                    user.ID = reader.GetInt32(0);
                    user.UserName = reader.GetString(1);
                    user.Passsword = reader.GetString(2); //not suggestion
                    if (!reader.IsDBNull (3))
                    {
                        //如果email的查詢結果不為空,則為model的email屬性賦值
                        user.Email = reader.GetString(3);
                    }                  
                }
                //返回model層例項出來的user(此時已賦好值)
                return user;
            }
        }
    }
}

namespace Login.DAL
{
    public  class ScoreDAO
    {
        public void UpdateScore (string userID,int value)
        {
            //定義一個數據連線conn,using之後連線自動關閉
            using (SqlConnection conn = new SqlConnection(DbUtil.ConnString))
            {
                //定義一個插入語句
                SqlCommand cmd = conn.CreateCommand();
                cmd.CommandText = @"INSERT INTO SCORES(ID,Score) values(@ID,@Score)";

                //以userID和value作為插入條件,賦給cmd
                cmd.Parameters.Add(new SqlParameter("@ID", userID));
                cmd.Parameters.Add(new SqlParameter("@Score", value ));

                //執行插入操作
                conn.Open();
                cmd.ExecuteNonQuery();
            }

        }
    }
}

總結

在進行三層的時候,最重要的一點就是要弄清楚各層之間的功能,明白層與層之間的呼叫關係,在程式碼執行過程中,認真跟著程式碼走幾遍,清楚實現的原理。