三層架構基礎

三層是什麼

三層架構(3-tier architecture)就是將整個業務應用劃分爲:

  • 界面層(User Interface Layer)

作用: 向用戶展現特定業務數據,採集用戶的輸入信息和操作
【PS:設計原則:用戶至上,兼顧簡潔】

  • 業務邏輯層(Business Logic Layer)

作用: 主要是負責對數據層的操作,吧一些數據層的操作進行組合。

  • 數據訪問層(Data Access Layer)

作用: 和數據源打交道,進行Select,Insert/Update,Delete等操作。

三層的目的
  • 高內聚,低耦合
三層何時使用

何時使用三層
當你的業務複雜到一定程度,當你的程序存儲到相應的數據庫的獨立的數據存儲集中時需要:把數據訪問脫離業務,業務脫離UI。此種情況下:UI只需要呼叫業務訪問層就可以使用。

三層的具體應用
  1. D層只提供基本的數據訪問,不包含任何業務相關的邏輯處理。
  2. U層只負責顯示和採集用戶操作,不包含任何的業務相關的邏輯處理
  3. B層負責處理業務邏輯。通過獲取UI傳來的操作指令,決定執行業務邏輯,在需要訪問數據源的時候直接交給D層處理。處理完成後,返回必要數據給U層。
三層的優缺點

優點:

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

缺點:

☆ 降低了系統的性能。這是不言而喻的。如果不採用分層結構,很多業務可以直接造訪數據庫,以此獲取相應的數據,如今卻是必須通過中間層來完成。
☆ 有時會導致級聯的修改。這種修改體現在自上而下的方向。如果在表示層中需要增加一個功能,爲保證其設計符合分層結構,可能需要在相應的業務邏輯層和數據訪問層中都增加相應的代碼。
☆ 增加了開發成本。

三層間的引用

在這裏插入圖片描述

三層的代碼

U層代碼:

private void BTLogin_Click(object sender, EventArgs e)
{ 
    try
    //對try塊代碼進行異常捕捉,
    //如無異常則進行直try塊結束,
    //如有異常則跳轉進入catch塊。
    {
        string userName = txtUserName.Text.Trim();
        string password = txtPassword.Text;
        Login.BLL.LoginManager mgr = new Login.BLL.LoginManager();
        //將用戶輸入的數據傳給BLL,在下面一句的使用中,就直接從BLL調用數據
        Login.Model.UserInfo user = mgr.UserLogin(userName, password);
        //在這裏就可以返回model裏的userinfo
        MessageBox.Show("登陸用戶:" + user.UserName);
    }
    catch (Exception ex)
    //處理異常。如下進行處理
    {
        MessageBox.Show(ex.Message);
    }
}

B層代碼

public class LoginManager
    {
        public Login.Model.UserInfo UserLogin(string userName,string password)
            //獲取UI傳來的指令UserLogin和數據Username還有password,可以返回model裏的userinfo了
        { 
            
            Login.DAL.UserDAO uDao = new Login.DAL.UserDAO();
            Login.Model.UserInfo user = uDao.SelectUser(userName, password);
            //調用userDao的selectUser方法,返回Model裏的UserInfo

            if (user != null)//登錄成功
            {
                Login.DAL.ScoreDAO sDao = new Login.DAL.ScoreDAO();
                sDao.UpdateScore(userName, 10);
                //調用ScoreDAO裏的UpdateScores增加積分的方法,選擇用戶名,增加十個積分
                return user;
            }
            else
            {
                throw new Exception("登陸失敗。");
                //拋出異常
            }
        }
    }

D層代碼

public class ScoreDAO
    {
        public void UpdateScore(string userName, int value)
            //寫一個增加積分的方法,從B層獲取數據
        {
            using (SqlConnection conn = new SqlConnection(DbUtil.ConnString))
            {
                SqlCommand cmd = conn.CreateCommand();
                cmd.CommandText = @"INSERT INTO SCORES (UserName, Score) Values(@UserName,@Score)";
                cmd.Parameters.Add(new SqlParameter("@UserName", userName));
                cmd.Parameters.Add(new SqlParameter("@Score", value));

                conn.Open();
                cmd.ExecuteNonQuery();

            }
        }
    }

public class UserDAO
    {
        public Login.Model.UserInfo SelectUser(string userName, string password)
            //寫一個方法,根據用戶名和密碼判斷,返回一個數據模型,
        {
            using (SqlConnection conn = new SqlConnection(DbUtil.ConnString))
            //有了上面的這個using ,connection就可以自動關閉了,
            {
                SqlCommand cmd = conn.CreateCommand();
                cmd.CommandText = @"SELECT ID,UserName,Password,Email
                                  FROM USERS WHERE UserName=@UserName AND Password=@Password";
                cmd.CommandType = CommandType.Text;
                cmd.Parameters.Add(new SqlParameter("@UserName", userName));
                cmd.Parameters.Add(new SqlParameter("@Password", password));

                conn.Open();
                SqlDataReader reader = cmd.ExecuteReader();

                Login.Model.UserInfo user = null;
                //局部變量進行賦值
                while (reader.Read())
                {
                    if (user ==null)
                    {
                    //對象沒有被實例,則創建實例
                        user = new Login.Model.UserInfo();

                    }
                    user.ID = reader.GetInt32(0);
                    //將數據庫第一列的數據以Int32的格式返回
                    user.UserName = reader.GetString(1);
                    //將數據庫第二列的數據以Int32的格式返回
                    user.Password = reader.GetString(2);
                    //將數據庫第三列的數據以int32的格式返回

                    if (!reader.IsDBNull(3))
                    {
                        user.Email = reader.GetString(3);
                    }

                }
                return user;

            }
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章