在簡單的三層登陸完成之后,我又在其中加入了設計模式,其中包括抽象工廠+反射和外觀模式.關于設計模式,在學習三層之前我們已經系統的學習過,可是在這次往機房收費系統中加設計模式時,還是感覺無從下手,出現了學沒有致用的尷尬情景.不過這也體現了我們提高班學習中項目驅動的優勢.
接下來是我的一些現有思路,可能還不很準確,期待讀者朋友的指點.
先說一下簡單的三層登陸思想吧:
我們現階段接觸的三層就是最基本的三層--UI層,BLL層和DAL層.關于這三者之間的關系,在我前面博客中有所涉及,如果有興趣,你可以參看:三層架構入門.
言歸正傳,理論知識我們知道了,在機房收費系統中,我們究竟是如何利用這三層來簡化靈活我們的代碼的呢?(由于.NET版本的登陸已經加入設計模式,所以簡單三層用C#語言來展示.)
大家可以先看下主體代碼:
UI層: 代碼如下:
[csharp]?view plaincopyprint?
<span?style="font-size:18px;">private?void?btnOK_Click(object?sender,?EventArgs?e)?? ????????{?? ????????????UserInfo?user?=?new?UserInfo();?? ?????????????? ????????????string?UserName?=?txtUserName.Text.Trim();?? ????????????string?Password?=?txtPassword.Text.Trim();?? ????????????user.UserName=UserName?;?? ????????????user.Password?=?Password;?? ?????????????? ????????????LoginManager?mgr?=?new?LoginManager();?? ????????????UserInfo?user2?=?new?UserInfo();?? ????????????user2?=?mgr.UserLogin(user);?? ????????????MessageBox.Show("登錄用戶:"?+?user.UserName);?? ????????}?? </span>??
U層,就是我們窗體類,是用戶唯一可以看到的部分.其中不涉及連接數據庫,也不會包括業務邏輯.它主要負責接收用戶輸入指令并傳給實體類,再有實體類傳給B層,進行業務邏輯的判斷.同時它也會根據B層產生的不同結果來及時反饋給用戶.
BLL層: 代碼如下:
[csharp]?view plaincopyprint?
<span?style="font-size:18px;">public??class?LoginManager?? ????{?? ????????public?UserInfo?UserLogin(UserInfo?user)?? ????????{?? ?????????????? ????????????UserDAO?uDAO?=?new?UserDAO();?? ????????????user?=?uDAO.SelectUser(user??);?? ?????????????? ????????????if?(user?!=?null)?? ????????????{?? ????????????????ScoreDAO?sDAO?=?new?ScoreDAO();?? ????????????????sDAO.UpdateScore(user,?10);?? ????????????????return?user;?? ????????????}?? ????????????else?? ????????????{?? ????????????????throw?new?Exception("登錄失敗!");?? ????????????}?? ????????}?? </span>??
這一層是業務邏輯層,顧名思義,它主要負責系統中的絕大部分邏輯判斷,一旦U層或者D層出現業務邏輯判斷,我們就要考慮,它是不是應該放在B層.
DAl層: 代碼如下:
[csharp]?view plaincopyprint?
<span?style="font-size:18px;">namespace?Login.DAL?? {?? ?????public??class?UserDAO?? ????{?? ??????????? ??????????? ??????????? ??????????? ??????????? ????????public?UserInfo??SelectUser(UserInfo?user)?? ????????{?????????? ????????????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",user.UserName??));?? ????????????????cmd.Parameters.Add(new?SqlParameter?("@Password",user.Password?));?? ????????????????conn.Open();?? ?? ????????????????SqlDataReader?reader?=?cmd.ExecuteReader();?? ????????????????user=null;?? ????????????????while?(reader?.Read?())?? ????????????????{?? ????????????????????if?(user?==?null)?? ????????????????????{?? ????????????????????????user?=?new?UserInfo();?? ????????????????????}?? ????????????????????user.ID?=?reader.GetInt32(0);?? ????????????????????user.UserName?=?reader.GetString(1);?? ????????????????????user.Password?=?reader.GetString(2);?? ????????????????????if?(!reader.IsDBNull(3))??? ????????????????????{?? ????????????????????????user.Email?=?reader.GetString(3);?? ????????????????????}?? ????????????????}?? ????????????????return?user;?????? ????????????}?? ????????}?? ????}?? }?? </span>??
從以上的代碼就可以看出,D層主要是連接數據庫,從數據庫中讀取信息,然后再以實體的形式傳給B層,B層傳給U層,最后表現在用戶面前.
?
上述是沒有添加設計模式的簡單三層登陸,下面就要談一談為什么要加設計模式,以及如何添加設計模式了.
設計模式(Design pattern)是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結.使用設計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。也許這樣說讀者還是不大明白,下面的代碼展示或許可以給您一些啟示.
首先說一下抽象工廠+反射,在機房登錄中的應用(只展示主體代碼,方便理解).
Abstract Factory: 抽象工廠接口,它里面包含所有產品創建的抽象方法.工廠類被BLL層調用,并調用IDAL接口,使用配置文件讀取數據庫字符串.通過反射技術,解除簡單工廠更換數據庫時的分支判斷帶來的耦合.
代碼如下:
[vb]?view plaincopyprint?
<span?style="font-size:18px;">Imports?System.Configuration?? Imports?System.Reflection?? Imports?IDAL?? ?? Public?Class?SqlFactory?? ????Private?Shared?ReadOnly?AssemblyName?As?String?=?"DAL"?? ?????? ????Private?Shared?DB?As?String?=?ConfigurationManager.AppSettings("strDB")?? ? #Region?"獲取用戶信息"?? ????Public?Shared?Function?CreatGetUserInfo()?As?IDAL.IGetUserInfo?? ????????Dim?UserInfo?As?IGetUserInfo?? ????????Dim?ClassName?As?String?? ?????????? ????????ClassName?=?AssemblyName?+?"."?+?DB?+?"D_GetUserInfo"?? ????????UserInfo?=?CType(Assembly.Load(AssemblyName).CreateInstance(ClassName),?IDAL.IGetUserInfo)?? ????????Return?UserInfo?? ????End?Function?? #End?Region?? </span>??
IDAL接口:? 被B層和D層調用,使得B層和D層的耦合度極大降低.
[vb]?view plaincopyprint?
<span?style="font-size:18px;">Imports?Entity?? ?? Public?Interface?IGetUserInfo?? ????Function?GetUserInfo(ByVal?e_Users?As?Entity.E_UserInfoEntity)?As?DataTable?? End?Interface?? </span>??
BLL層: 定義接口類,并使用工廠類SqlFactory方法反射實例化相應的DAl類.這時候B層和D層已經完全不再耦合,B層或者D層的任何變動,都不會影響另一層.(這就是我們使用抽象工廠加反射的最大用處了.)
[vb]?view plaincopyprint?
<span?style="font-size:18px;">Imports?Entity?? Imports?IDAL?? Imports?DBFactory.SqlFactory?? Imports?DAL?? ?? Public?Class?B_UserInfo?? ?????? ????Public?SqlFactory?As?New?DBFactory.SqlFactory?? #Region?"驗證用戶密碼"?? ????Public?Function?VerifyPassword(ByVal?EUserInfo?As?E_UserInfoEntity)?As?Boolean?? ?? ?????????? ????????Dim?IGetPWD?As?IDAL.IGetUserInfo?? ????????IGetPWD?=?DBFactory.SqlFactory.CreatGetUserInfo?? ????????Dim?dtUserInfo?As?DataTable?? ????????dtUserInfo?=?IGetPWD.GetUserInfo(EUserInfo)?? ?? ????????If?dtUserInfo.Rows.Count?=?0?Then?? ????????????Throw?New?Exception("該用戶還未注冊!")?? ????????????Return?False?? ????????End?If?? ?? ?????????? ????????If?EUserInfo.Passwrod?=?Trim(dtUserInfo.Rows(0).Item(1))?Then?? ????????????Return?True?? ????????Else?? ????????????Return?False?? ????????End?If?? ????End?Function?? #End?Region?? End?Class?? </span>??
抽象工廠和反射解耦和B層和D層.接下來的外觀模式就要解耦U層和B層了.
Facade類: 在簡單的三層中,界面層的登陸需要根據B層返回的值再進行判斷,這樣B層和U層的耦合度是比較高的.而加入外觀模式后,上面提到的對B層返回值進行判斷就可以移到外觀類中.這樣就充分實現了B層和U層的分離.
[vb]?view plaincopyprint?
<span?style="font-size:18px;">Imports?Entity?? Imports?BLL?? ?? Public?Class?Login?? ????Private?bUserInfo?As?New?B_UserInfo?? ????Dim?blnFlag?As?Boolean?=?False?? ?????? ?????? ?????? ?????? ?????? ?????? ????Public?Function?IsPassword(ByVal?eUserInfo?As?E_UserInfoEntity)?As?Boolean?? ????????Try?? ????????????blnFlag?=?bUserInfo.VerifyPassword(eUserInfo)?? ????????Catch?ex?As?Exception?? ????????????MsgBox(ex.Message,?vbOKOnly,?"提示信息")?? ????????End?Try?? ?? ????????If?blnFlag?=?True?Then?? ????????????Return?True?? ????????Else?? ????????????MsgBox("密碼錯誤,請重新輸入!")?? ????????????Return?False?? ????????End?If?? ????End?Function?? End?Class?? </span>??
UI層: ? 外觀層在對B層返回值進行判斷之后,返回信息給UI層.這樣U層和B層就實現了分離,兩者中任何一層發生變化都不用修改另一層的代碼.
[vb]?view plaincopyprint?
<span?style="font-size:18px;">Imports?Entity?? Imports?BLL?? Imports?Facade.Login?? ?? ?? Public?Class?frmLogin?? ????Public?bUserInfo?As?New?B_UserInfo?? ????Public?faUserInfo?As?New?Facade.Login?? ?? ????Private?Sub?btnOK_Click(ByVal?sender?As?System.Object,?ByVal?e?As?System.EventArgs)?Handles?btnOK.Click?? ????????Dim?aUserInfo?As?New?Entity.E_UserInfoEntity?? ????????Dim?blnFlag?As?Boolean?=?False?? ?? ????????aUserInfo.UserID?=?Trim(txtUserName.Text)?? ????????aUserInfo.Passwrod?=?Trim(txtPassword.Text)?? ?? ?????????? ????????Try?? ????????????blnFlag?=?faUserInfo.IsPassword(aUserInfo)?? ????????Catch?ex?As?Exception?? ????????????MsgBox(ex.Message,?vbOKOnly,?"提示信息")?? ????????End?Try?? ?? ????????If?blnFlag?=?True?Then?? ????????????frmMain.Show()?? ????????End?If?? ????End?Sub?? End?Class?? </span>??
上述是我現階段對三層和部分設計模式的理解,錯誤之處希望讀者朋友多多指教!
總結
以上是生活随笔為你收集整理的机房收费系统=三层+设计模式的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。