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

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

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

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

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

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

   UI: 代码如下:

[csharp] view plaincopyprint?
  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: 代码如下:

[csharp] view plaincopyprint?
  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层: 代码如下:

[csharp] view plaincopyprint?
  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. cmd.Parameters.Add(new SqlParameter ("@UserName",user.UserName  ));
  18. cmd.Parameters.Add(new SqlParameter ("@Password",user.Password ));
  19. conn.Open();
  20. SqlDataReader reader = cmd.ExecuteReader();
  21. user=null;
  22. while (reader .Read ())//Read()方法:读取一个表的记录
  23. {
  24. if (user == null)
  25. {
  26. user = new UserInfo();
  27. }
  28. user.ID = reader.GetInt32(0);
  29. user.UserName = reader.GetString(1);
  30. user.Password = reader.GetString(2);
  31. if (!reader.IsDBNull(3))
  32. {
  33. user.Email = reader.GetString(3);
  34. }
  35. }
  36. return user;
  37. }
  38. }
  39. }
  40. }
  41. </span>

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

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

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

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

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

   代码如下:

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

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

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

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

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

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

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

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

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

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

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

机房收费系统=三层+设计模式相关推荐

  1. 机房收费系统之抽象工厂篇

    机房收费系统vb.net个人版已完成,在此过程中分层的好处在系统的完成过程中得到了很好的体会.第一遍用的是纯三层做的,这几天又在此基础上又重构了登录的demo,加上抽象工厂和配置文件的使用.下面以登录 ...

  2. 重构机房VB.NET机房收费系统个人重构版你都学会了什么(之一)

    每日一贴,今天的内容关键字为重构机房 在VB.NET机房收费系统个人重构版时你都学会了什么?在开始第二遍的机房收费系统个人重构时,我发明不知不觉竟接触了很多很多之前不晓得的货色,也学到了很多新知识.下 ...

  3. 重构机房收费系统(二)

    接上篇<机房收费系统重构(一)> 二.概要设计 完成了用例图,并用结合用例图完善了一下需求分析说明书,忘记是第几次修订需求分析说明书.有了用例图,很自然就进入了概要设计阶段.我认为这一阶段 ...

  4. 【机房收费系统】多么痛的领悟

    这次机房收费系统,是全部的项目中,自己完毕的最不惬意的了. 时间之长.效率之慢.一開始.就感觉无从下手,但总会相信自己能慢慢的进入状态.最终有机会自己练练手了.也自觉得之前自己设计模式学的还不错.也最 ...

  5. 重构机房收费系统(一)

    从10月1号开始重构学校机房收费系统,没想到这次重构,推翻,再重构--用了两周时间. 这次整体架构采用三层,并融入了一些设计模式. 下面介绍这次重构的过程: 一.从UML用例图开始 对于机房收费系统的 ...

  6. 机房收费系统个人重构版:暮然回首,灯火阑珊

    [背景]   在蹒跚中自己的机房收费系统个人重构版已完结:回望这一路征程,感慨颇多:快乐过,痛苦过:紧张过,放松过!真可谓:酸甜苦辣,五味杂陈. [比一比] VB.Net版个人重构版比VB版机房收费系 ...

  7. 机房收费系统总结之5——抽象工厂+反射+配置文件

    起初,机房收费系统用纯三层在做,三层结构已把高内聚,低耦合的思想发挥的淋漓尽致.因为一直听说"抽象工厂",也开始尝试去应用,经过了一番尝试,也OK了.其中当然会用到反射和配置文件, ...

  8. 机房收费系统总结——心态篇

    写机房收费系统的这三个月,对写代码的认识更深刻了,对学习的过程也更多了点体会. 多敲代码:从软件工程到UML,C#,设计模式,再到vb.net.这个过程中只敲了敲教程中的代码,没实现过其他什么例子,也 ...

  9. VB.NET版机房收费系统---七仙女之系统登录

    VB.NET第一版机房收费系统,告一段落,验收的时候,问题也是大大的存在,没有用上设计模式,什么触发器,存储过程,都没有用上,看看其她小伙伴的,七层实现登录?那是什么东东,相比较我的三层而言,多了两倍 ...

最新文章

  1. 电脑 计算机服务打不开怎么办理,电脑xlsx打不开怎么办
  2. 猫头鹰的深夜翻译:API网关的重要性
  3. 北邮OJ 2016 网预-Square Coins
  4. ansible-playbook组件解析及操作全解
  5. uap连接oracle,UAP环境初始化操作手册Oralce版.pdf
  6. Qt QtCreator 所有版本官方下载地址
  7. SoftGrid教程——综合应用
  8. java中length,length(),size()区别
  9. CMake快速入门教程-实战
  10. (day 1)创建项目--3【创建应用】
  11. http basic认证
  12. 实对称矩阵的一些性质(不包含证明)
  13. html条形统计图,js实现条形统计图
  14. matlab计算胎心率,基于盲分离的胎心音心率检测算法与实现
  15. wpsppt页面卷曲在哪里_2013版ppt怎么制作页面卷曲动画效果
  16. OSChina 周一乱弹 —— 为什么人类和人工智能定要一战
  17. 从零开始Android游戏编程(第二版)
  18. “5G+4G”聚合路由器多链路图传技术巩固安防监控行业
  19. 性能测试基础(四)吞吐量
  20. Linux驱动加载实例

热门文章

  1. 【Android 逆向】修改运行中的 Android 进程的内存数据 ( 使用 IDA 分析要修改的内存特征 | 根据内存特征搜索修改点 | 修改进程内存 )
  2. 【FFmpeg】FFmpeg 相关术语简介 ( 容器 | 媒体流 | 数据帧 | 数据包 | 编解码器 | 复用 | 解复用 )
  3. 网页分享到微信、微博、QQ空间、百度贴吧等
  4. LeetCode-337 House Robber III
  5. 流程图软件draw.io
  6. 监控Tomcat解决方案(监控应用服务器系列文章分享)
  7. OC中protocol、category和继承的区别
  8. 常用js代码整理、收集
  9. mysql存储过程获取sqlstate message_text
  10. IT职场人生系列之十四:经验积累