三层架构 详解
文章目錄
- 前言
- 什么是三層架構?
- 為什么要用三層架構?
- 優缺點:
- 怎么用三層架構?
- 實例演練:
前言
當看到一個陌生的名詞時你會怎么想?what?way?how? 現在就按照這個思維框架走進“三層架構”。
什么是三層架構?
在軟件體系架構設計中,分層式結構是最常見,也是最重要的一種結構。微軟推薦的分層式結構一般分為三層,從下至上分別為:數據訪問層、業務邏輯層(又或稱為領域層)、表示層。
1、表示層(UI):通俗講就是展現給用戶的界面,即用戶在使用一個系統的時候他的所見所得。
2、業務邏輯層(BLL):針對具體問題的操作,也可以說是對數據層的操作,對數據業務邏輯處理。
3、數據訪問層(DAL):該層所做事務直接操作數據庫,針對數據的增添、刪除、修改、查找等。
微軟的DNA架構定義了三個層:表示層(presentation),業務邏輯層(business),和數據訪問層(data access)。具體又分為:界面外觀層、界面規則層、業務接口層、業務邏輯層、實體層、數據訪問層、數據存儲層共七層,其具體的調用如下圖所示:
為什么要用三層架構?
對于一個簡單的應用程序來說,代碼量不是很多的情況下,一層結構或二層結構開發完全夠用,沒有必要將其復雜化,如果對一個復雜的大型系統,設計為一層結構或二層結構開發,那么這樣的設計存在很嚴重缺陷。
分層開發其實是為大型系統服務的。在開發過程中,初級程序人員出現相似的功能經常復制代碼,那么同樣的代碼寫那么多次,不但使程序變得冗長,更不利于維護,一個小小的修改或許會涉及很多頁面,經常導致異常的產生使程序不能正常運行。最主要的面向對象的思想沒有得到絲毫的體現,打著面向對象的幌子卻依然走著面向過程的道路。
意識到這樣的問題,初級程序人員開始將程序中一些公用的處理程序寫成公共方法,封裝在類中,供其它程序調用。例如寫一個數據操作類,對數據操作進行合理封裝,在數據庫操作過程中,只要類中的相應方法(數據添加、修改、查詢等)可以完成特定的數據操作,這就是數據訪問層,不用每次操作數據庫時都寫那些重復性 的數據庫操作代碼。在新的應用開發中,數據訪問層可以直接拿來用。面向對象的三大特性之一的封裝性在這里得到了很好的體現?,F在找到了面向對象的感覺,代碼量較以前有了很大的減少,而且修改的時候也比較方便,也實現了代碼的重用性。
優缺點:
(一)優點
1、開發人員可以只關注整個結構中的其中某一層;
2、可以很容易的用新的實現來替換原有層次的實現;
3、可以降低層與層之間的依賴;
4、有利于標準化;
5、利于各層邏輯的復用。
(二)缺點
1、降低了系統的性能。這是不言而喻的。如果不采用分層式結構,很多業務可以直接造訪數據庫,以此獲取相應的數據,如今卻必須通過中間層來完成。
2、有時會導致級聯的修改。這種修改尤其體現在自上而下的方向。如果在表示層中需要增加一個功能,為保證其設計符合分層式結構,可能需要在相應的業務邏輯層和數據訪問層中都增加相應的代碼。
3、增加了開發成本。
怎么用三層架構?
不是所有的系統都需要使用三層架構,在一開始學習這塊知識的時候有可能會存在誤區。對于簡單的問題我們沒有必要把它復雜化,甚至有可能會畫蛇添足、多此一舉。
不需要使用的情況:
1業務邏輯簡單。 2、沒有真正的數據存儲層。需要使用的情況:
既有數據訪問層DAL又有業務邏輯層BLL,也就是說當業務復雜到一定程度后,數據需要單獨的存儲到相對獨立的介質中時,需要把數據訪問脫離開業務單獨存在,把業務脫離開UI單獨存在,UI達到業務只需要呼叫業務訪問層即可實現跟用戶訪問的交互。這種情況下我們才使用三層結構。
實例演練:
現在有一個積分系統,學生每登錄一次可獲得10積分獎勵。代碼入下:
UI層:
BLL層:
namespace LoginBll {//管理登錄類,用于判斷用戶是否登陸成功public class LoginManager{//UI層傳遞的是UserInfo方法,數據是Username,passwordpublic LoginModel.UserInfo UserLogin(string userName, string password) //UserLogin方法,判斷登錄信息是否正確{LoginDAL.UserDAO uDao = new LoginDAL.UserDAO(); //實例化一個數據層登錄LoginModel.UserInfo user = uDao.SelectUser(userName, password); //實例化一個Model,用于給數據層的SelectUser賦值if (user!=null){LoginDAL.SocreDAO sDao = new LoginDAL.SocreDAO();sDao.UpdateScore(user.ID ,userName, 10);//增加積分return user;}else{throw new Exception("登錄失敗");}}}DAL層:
class DBUtil{public static string ConnString = @"Server= (Local);Database=Login;User ID=sa;Password=123";}public class SocreDAO{public void UpdateScore(int ID,string userName,int value){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("@ID", ID));cmd.Parameters.Add(new SqlParameter ("@UserName",userName ));cmd.Parameters.Add(new SqlParameter("@Score", value ));conn.Open();//執行sql句,返回受影響行數cmd.ExecuteNonQuery();}}}public class UserDAO{public LoginModel.UserInfo SelectUser(string userName, string password){using (SqlConnection conn = new SqlConnection(DBUtil.ConnString))//建立數據庫連接{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));cmd.CommandText = @"SELECT ID,UserName,Password,Email FROM USERS WHERE UserName=@UserName AND Password=@Password "; //設置操作語句conn.Open();//打開連接//創建數據讀取對象,循環讀取數據SqlDataReader reader = cmd.ExecuteReader(); //此方法用于用戶進行的查詢操作,使用SqlDataReader對象的Read();方法進行逐行讀取。LoginModel.UserInfo user = null;while (reader.Read()){if (user==null){user = new LoginModel.UserInfo();}user.ID =reader.GetInt32(0); //獲取指定列的32位有符號整數形式的值 user.UserName = reader.GetString(1);user.Password = reader.GetString(2);if (!reader.IsDBNull (3)){user.Email = reader.GetString(3);}}return user;}}}實體層:
//數據模型,用于三層之間傳輸數據public class UserInfo{public int ID { get; set; }public string UserName { get; set; }public string Password { get; set; }public string Email { get; set; }}原文鏈接:https://blog.csdn.net/duyusean/article/details/70882262
總結
- 上一篇: 常见字典用法集锦及代码详解
- 下一篇: cms开发(CMS开发)