机房收费系统=三层+设计模式

原创 2015年11月18日 20:11:26

在简单的三层登陆完成之后,我又在其中加入了设计模式,其中包括抽象工厂+反射和外观模式.关于设计模式,在学习三层之前我们已经系统的学习过,可是在这次往机房收费系统中加设计模式时,还是感觉无从下手,出现了学没有致用的尴尬情景.不过这也体现了我们提高班学习中项目驱动的优势.

   接下来是我的一些现有思路,可能还不很准确,期待读者朋友的指点.

   先说一下简单的三层登陆思想吧:

   我们现阶段接触的三层就是最基本的三层--UI,BLL层和DAL.关于这三者之间的关系,在我前面博客中有所涉及,如果有兴趣,你可以参看:三层架构入门

   言归正传,理论知识我们知道了,在机房收费系统中,我们究竟是如何利用这三层来简化灵活我们的代码的呢?(由于.NET版本的登陆已经加入设计模式,所以简单三层C#语言来展示.)

   大家可以先看下主体代码:

   UI: 代码如下:

  1. <span style="font-size:18px;">private void btnOK_Click(object sender, EventArgs e)  
  2.         {  
  3.             UserInfo user = new UserInfo();  
  4.             //向实体层传递参数  
  5.             string UserName = txtUserName.Text.Trim();  
  6.             string Password = txtPassword.Text.Trim();  
  7.             user.UserName=UserName ;  
  8.             user.Password = Password;  
  9.             //实例化BLL层,并调用BLL层方法  
  10.             LoginManager mgr = new LoginManager();  
  11.             UserInfo user2 = new UserInfo();  
  12.             user2 = mgr.UserLogin(user);  
  13.             MessageBox.Show("登录用户:" + user.UserName);  
  14.         }  
  15. </span>  

   U,就是我们窗体类,是用户唯一可以看到的部分.其中不涉及连接数据库,也不会包括业务逻辑.它主要负责接收用户输入指令并传给实体类,再有实体类传给B,进行业务逻辑的判断.同时它也会根据B层产生的不同结果来及时反馈给用户.


   BLL: 代码如下:

  1. <span style="font-size:18px;">public  class LoginManager  
  2.     {  
  3.         public UserInfo UserLogin(UserInfo user)  
  4.         {  
  5.             //实例化DAL层,并调用DAL层方法  
  6.             UserDAO uDAO = new UserDAO();  
  7.             user = uDAO.SelectUser(user  );  
  8.             //逻辑判断代码  
  9.             if (user != null)  
  10.             {  
  11.                 ScoreDAO sDAO = new ScoreDAO();  
  12.                 sDAO.UpdateScore(user, 10);  
  13.                 return user;  
  14.             }  
  15.             else  
  16.             {  
  17.                 throw new Exception("登录失败!");  
  18.             }  
  19.         }  
  20. </span>  

   这一层是业务逻辑层,顾名思义,它主要负责系统中的绝大部分逻辑判断,一旦U层或者D层出现业务逻辑判断,我们就要考虑,它是不是应该放在B.


   DAl: 代码如下:

  1. <span style="font-size:18px;">namespace Login.DAL  
  2. {  
  3.      public  class UserDAO  
  4.     {  
  5.          /// <summary>  
  6.          /// 连接数据库,获取用户信息  
  7.          /// </summary>  
  8.          /// <param name="user">用户信息实体</param>  
  9.          /// <returns>用户信息</returns>  
  10.         public UserInfo  SelectUser(UserInfo user)  
  11.         {          
  12.             using (SqlConnection conn = new SqlConnection(DbUtil.ConnString))   //有待填写  
  13.             {  
  14.                 SqlCommand cmd = conn.CreateCommand();  
  15.                 cmd.CommandText = @"SELECT ID, UserName,Password,Email from Users where UserName=@UserName and Password=@Password";  
  16.                 cmd.CommandType = CommandType.Text;  
  17.                   
  18.                 cmd.Parameters.Add(new SqlParameter ("@UserName",user.UserName  ));  
  19.                 cmd.Parameters.Add(new SqlParameter ("@Password",user.Password ));  
  20.                 conn.Open();  
  21.   
  22.                 SqlDataReader reader = cmd.ExecuteReader();  
  23.                 user=null;  
  24.                 while (reader .Read ())//Read()方法:读取一个表的记录  
  25.                 {  
  26.                     if (user == null)  
  27.                     {  
  28.                         user = new UserInfo();  
  29.                     }  
  30.                     user.ID = reader.GetInt32(0);  
  31.                     user.UserName = reader.GetString(1);  
  32.                     user.Password = reader.GetString(2);  
  33.                     if (!reader.IsDBNull(3))   
  34.                     {  
  35.                         user.Email = reader.GetString(3);  
  36.                     }  
  37.                 }  
  38.                 return user;      
  39.             }  
  40.         }  
  41.     }  
  42. }  
  43. </span>  

   从以上的代码就可以看出,D层主要是连接数据库,从数据库中读取信息,然后再以实体的形式传给B,B层传给U,最后表现在用户面前.

 

   上述是没有添加设计模式的简单三层登陆,下面就要谈一谈为什么要加设计模式,以及如何添加设计模式了.

   设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结.使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。也许这样说读者还是不大明白,下面的代码展示或许可以给您一些启示.

   首先说一下抽象工厂+反射,在机房登录中的应用(只展示主体代码,方便理解).

   Abstract Factory: 抽象工厂接口,它里面包含所有产品创建的抽象方法.工厂类被BLL层调用,并调用IDAL接口,使用配置文件读取数据库字符串.通过反射技术,解除简单工厂更换数据库时的分支判断带来的耦合.

   代码如下:

  1. <span style="font-size:18px;">Imports System.Configuration  
  2. Imports System.Reflection  
  3. Imports IDAL  
  4.   
  5. Public Class SqlFactory  
  6.     Private Shared ReadOnly AssemblyName As String = "DAL"  
  7.     '使用配置文件,读取数据库连接字符  
  8.     Private Shared DB As String = ConfigurationManager.AppSettings("strDB")  
  9.  
  10. #Region "获取用户信息"  
  11.     Public Shared Function CreatGetUserInfo() As IDAL.IGetUserInfo  
  12.         Dim UserInfo As IGetUserInfo  
  13.         Dim ClassName As String  
  14.         '反射技术,解除简单工厂更换数据库时的分支判断带来的耦合  
  15.         ClassName = AssemblyName + "." + DB + "D_GetUserInfo"  
  16.         UserInfo = CType(Assembly.Load(AssemblyName).CreateInstance(ClassName), IDAL.IGetUserInfo)  
  17.         Return UserInfo  
  18.     End Function  
  19. #End Region  
  20. </span>  

   IDAL接口:  B层和D层调用,使得B层和D层的耦合度极大降低.

  1. <span style="font-size:18px;">Imports Entity  
  2.   
  3. Public Interface IGetUserInfo  
  4.     Function GetUserInfo(ByVal e_Users As Entity.E_UserInfoEntity) As DataTable  
  5. End Interface  
  6. </span>  

   BLL:  定义接口类,并使用工厂类SqlFactory方法反射实例化相应的DAl.这时候B层和D层已经完全不再耦合,B层或者D层的任何变动,都不会影响另一层.(这就是我们使用抽象工厂加反射的最大用处了.)

  1. <span style="font-size:18px;">Imports Entity  
  2. Imports IDAL  
  3. Imports DBFactory.SqlFactory  
  4. Imports DAL  
  5.   
  6. Public Class B_UserInfo  
  7.     '创建工厂类,作用:创建接口对象  
  8.     Public SqlFactory As New DBFactory.SqlFactory  
  9. #Region "验证用户密码"  
  10.     Public Function VerifyPassword(ByVal EUserInfo As E_UserInfoEntity) As Boolean  
  11.   
  12.         '创建获得用户信息的接口  
  13.         Dim IGetPWD As IDAL.IGetUserInfo  
  14.         IGetPWD = DBFactory.SqlFactory.CreatGetUserInfo  
  15.         Dim dtUserInfo As DataTable  
  16.         dtUserInfo = IGetPWD.GetUserInfo(EUserInfo)  
  17.   
  18.         If dtUserInfo.Rows.Count = 0 Then  
  19.             Throw New Exception("该用户还未注册!")  
  20.             Return False  
  21.         End If  
  22.   
  23.         '判断密码是否正确  
  24.         If EUserInfo.Passwrod = Trim(dtUserInfo.Rows(0).Item(1)) Then  
  25.             Return True  
  26.         Else  
  27.             Return False  
  28.         End If  
  29.     End Function  
  30. #End Region  
  31. End Class  
  32. </span>  

   抽象工厂和反射解耦和B层和D层.接下来的外观模式就要解耦U层和B层了.

   Facade类: 在简单的三层中,界面层的登陆需要根据B层返回的值再进行判断,这样B层和U层的耦合度是比较高的.而加入外观模式后,上面提到的对B层返回值进行判断就可以移到外观类中.这样就充分实现了B层和U层的分离.

  1. <span style="font-size:18px;">Imports Entity  
  2. Imports BLL  
  3.   
  4. Public Class Login  
  5.     Private bUserInfo As New B_UserInfo  
  6.     Dim blnFlag As Boolean = False  
  7.     ''' <summary>  
  8.     ''' 对B层的返回值进行逻辑判断  
  9.     ''' </summary>  
  10.     ''' <param name="eUserInfo">用户信息实体</param>  
  11.     ''' <returns>用户信息正确返回True,错误返回False</returns>  
  12.     ''' <remarks></remarks>  
  13.     Public Function IsPassword(ByVal eUserInfo As E_UserInfoEntity) As Boolean  
  14.         Try  
  15.             blnFlag = bUserInfo.VerifyPassword(eUserInfo)  
  16.         Catch ex As Exception  
  17.             MsgBox(ex.Message, vbOKOnly, "提示信息")  
  18.         End Try  
  19.   
  20.         If blnFlag = True Then  
  21.             Return True  
  22.         Else  
  23.             MsgBox("密码错误,请重新输入!")  
  24.             Return False  
  25.         End If  
  26.     End Function  
  27. End Class  
  28. </span>  

   UI:   外观层在对B层返回值进行判断之后,返回信息给UI层.这样U层和B层就实现了分离,两者中任何一层发生变化都不用修改另一层的代码.

  1. <span style="font-size:18px;">Imports Entity  
  2. Imports BLL  
  3. Imports Facade.Login  
  4.   
  5.   
  6. Public Class frmLogin  
  7.     Public bUserInfo As New B_UserInfo  
  8.     Public faUserInfo As New Facade.Login  
  9.   
  10.     Private Sub btnOK_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles btnOK.Click  
  11.         Dim aUserInfo As New Entity.E_UserInfoEntity  
  12.         Dim blnFlag As Boolean = False  
  13.   
  14.         aUserInfo.UserID = Trim(txtUserName.Text)  
  15.         aUserInfo.Passwrod = Trim(txtPassword.Text)  
  16.   
  17.         '调用外观类的IsPassword方法进行逻辑判断  
  18.         Try  
  19.             blnFlag = faUserInfo.IsPassword(aUserInfo)  
  20.         Catch ex As Exception  
  21.             MsgBox(ex.Message, vbOKOnly, "提示信息")  
  22.         End Try  
  23.   
  24.         If blnFlag = True Then  
  25.             frmMain.Show()  
  26.         End If  
  27.     End Sub  
  28. End Class  
  29. </span>  

   上述是我现阶段对三层和部分设计模式的理解,错误之处希望读者朋友多多指教!

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

机房收费系统--设计模式思考

今天与阿真同学简略讨论了一下外观模式和抽象工厂+反射+配置文件在机房重构中的应用,引发了几个简单的思考,现与君共勉:...

机房收费系统完美设计——事务处理vs三层架构2

上一篇博客中简单介绍了事物处理中各个类从中起到的作用、系统设计中为什么要使用事物的处理,以及最简单的在三层架构中通过传递Transaction作为参数最简单的使用事物。          这一篇博客要...
  • hy6688_
  • hy6688_
  • 2013年05月25日 21:45
  • 1450

机房收费系统完美设计——事务处理VS三层架构

事务处理之前我的博客中有介绍的: SqlTransaction对事务的处理 当然这次也还是以介绍本地事务为主。   上面的博客中只是通过简单的例子介绍事务的应用,但是在三层架构中事务应该怎样使用呢,要...
  • hy6688_
  • hy6688_
  • 2013年05月16日 00:49
  • 2132

机房收费系统小结(只用三层做的)

逻辑问题。 因为和第一次做机房收费系统不同,这次做的时候无论退卡还是学生注销,删除系统用户都没有直接将表中的数据删除,而是设置的状态标志位,就像结账的标志位一样,在建立表结构的时候加上默认值,或是在...

VB.NET+三层 机房收费系统之组合查询

关系组合查询已经用去了4天的时间,每天都在痛苦中煎熬,绞尽脑汁,一句代码都要瞪大眼睛看好长时间,有时候,因为两句话颠倒了,就nothing了;有时候,因为table怎样能够转换成实体类型,将自己困住了...

【机房收费系统个人版】三层登陆

首先,三层登陆由四部分组成。分别是UI层、BLL层、DAL层和Models实体。UI层的作用是接收用户输入的数据,显示用户查询的数据,为用户提供一种交互式操作界面;BLL层是起到数据的承上启下作用,对...

重构机房收费系统—浅谈三层

机房收费系统重构,详细说明重构各个层的由来以及构建建议。

VB.net版机房收费系统——三层登录

VB.net版机房收费系统的三层登陆代码实现,命名规范很重要,写注释便于他人理解,也便于自己理清思路~...

组合查询(vb.net+三层架构之机房收费系统)

在机房收费系统中有三个窗体功能涉及到组合查询。vb版的组合查询和.net+三层架构版的组合查询还是有一些区别的。虽然有区别,但是,核心不变——拼接字符串。   为什么说组合查询是一个小难点? 1...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:机房收费系统=三层+设计模式
举报原因:
原因补充:

(最多只允许输入30个字)