机房重构之七层登录
2016-03-05 17:28
344 查看
目录
目录七层UML图
七层具体展示
UI层
Facade层
BLL层
Factory层
IDAL层
DAL层
sqlHelper层
Entity实体
遇到的问题
往sqlHelper里传参数时用数组
找不到指定文件
自己的小想法
结语
七层UML图
七层具体展示
UI层
Public Class frmLogin Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click '输入不能为空 If txtUserID.Text = "" Then MsgBox("请输入用户ID号", MessageBoxButtons.OK, MessageBoxIcon.Exclamation) txtUserID.Focus() End If If txtPassWord.Text = "" Then MsgBox("请输入密码", MessageBoxButtons.OK, MessageBoxIcon.Exclamation) txtPassWord.Focus() End If Try '实体获得窗体信息 Dim user As New Entity.UserInfo Dim facade As New Facade.LoginFacade user.userID = txtUserID.Text.Trim() user.passWord = txtPassWord.Text.Trim() '将U层信息传入外观层 Dim flag As Boolean Dim flagPSW As Boolean flag = facade.CheckUserID(user) 'flagPSW = facade.CheckPassWord(user) '显示结果,先判断用户是否存在,存在再判断密码,密码正确则登录成功,否则提示密码错误 If flag = False Then MsgBox("用户不存在,请重新输入", MessageBoxButtons.OK, MessageBoxIcon.Exclamation) txtUserID.Text = "" txtPassWord.Text = "" txtUserID.Select() txtUserID.Focus() Else flagPSW = facade.CheckPassWord(user) If flagPSW = False Then MsgBox("密码错误,请重新输入!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation) txtPassWord.Text = "" txtPassWord.Select() txtPassWord.Focus() Else MsgBox("登录成功!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation) txtUserID.Text = "" txtPassWord.Text = "" Me.Hide() End If End If Catch ex As Exception MsgBox("未知错误") End Try End Sub End Class
Facade层
Imports System.Reflection '添加反射引用 Imports System.Configuration '添加配置文件的引用 Imports System.Data Imports IDAL '反射+配置文件+抽象工厂实现数据访问 Public Class LoginFactory Private Shared ReadOnly AssemblyName As String = "DAL" '数据程序集名称&命名空间DAL Dim strDB As String = System.Configuration.ConfigurationSettings.AppSettings("DB") '使用配置文件 Public Function CreateIUser() As ILoginUser Dim classname As String = "DAL" + "." + strDB + "LoginDAL" '要实例化的D层类的名称 Dim IUser As ILoginUser 'CType函数将返回表达式显示的转换为指定数据类型、对象、结构、类或接口后的结果 IUser = CType(Assembly.Load(AssemblyName).CreateInstance(classname), ILoginUser) Return IUser End Function End Class
BLL层
Public Class LoginService Dim table As New DataTable Dim flag As Boolean Dim Factory As New Factory.LoginFactory Dim IUser As IDAL.ILoginUser Public Function CheckUserID(ByVal user As Entity.UserInfo) As Boolean IUser = Factory.CreateIUser() '调用工厂的CreateIUser方法创建IUser接口实例 table = IUser.SelectUser(user) If table.Rows.Count = 0 Then flag = False Else flag = True End If Return flag End Function Public Function CheckPassWord(ByVal user As Entity.UserInfo) As Boolean '逻辑判断都在B 层做,U层只负责显示 IUser = Factory.CreateIUser() table = IUser.SelectUser(user) If table.Rows(0).Item(2) = user.passWord Then flag = True Else flag = False End If Return flag End Function End Class
Factory层
Imports System.Reflection '添加反射引用 Imports System.Configuration '添加配置文件的引用 Imports System.Data Imports IDAL '反射+配置文件+抽象工厂实现数据访问 Public Class LoginFactory Private Shared ReadOnly AssemblyName As String = "DAL" '数据程序集名称&命名空间DAL Dim strDB As String = System.Configuration.ConfigurationSettings.AppSettings("DB") '使用配置文件 Public Function CreateIUser() As ILoginUser Dim classname As String = "DAL" + "." + strDB + "LoginDAL" '要实例化的D层类的名称 Dim IUser As ILoginUser 'CType函数将返回表达式显示的转换为指定数据类型、对象、结构、类或接口后的结果 IUser = CType(Assembly.Load(AssemblyName).CreateInstance(classname), ILoginUser) Return IUser End Function End Class
IDAL层
Public Interface ILoginUser Function SelectUser(ByVal user As Entity.UserInfo) As DataTable End Interface
DAL层
Imports System.Configuration Imports IDAL Imports System.Data.SqlClient Public Class LoginDAL : Implements IDAL.ILoginUser Private SqlFavor As New SqlHelper.SqlFavor '判断用户名是否存在 Public Function SelectUser(ByVal user As Entity.UserInfo) As DataTable Implements IDAL.ILoginUser.SelectUser Dim sql As String '储存查询语句 Dim table As DataTable '声明并实例化参数数组 Dim paras As SqlParameter() = {New SqlParameter("@userID", user.userID), New SqlParameter("@passWord", user.passWord)} '数组 'sql = "select * from Users where ID = @userID and PassWord = @passWord" sql = "select * from Users where ID = @userID" '调用SQLHelper中的ExecSelect方法来查询,并获取返回值 table = SqlFavor.ExecSelect(sql, CommandType.Text, paras) Return table End Function End Class
sqlHelper层
Imports System.Data Imports System.Data.SqlClient Imports System.Configuration '配置文件的引用 Public Class SqlFavor '数据库连接 Dim strConnection As String = "Server = jf; Database = Login; User ID = sa; PassWord = summer" Dim conn As New SqlConnection(strConnection) Dim cmd As New SqlCommand Public Function ExecSelect(ByVal cmdText As String, ByVal cmdType As CommandType, ByVal paras As SqlParameter()) As DataTable Dim sqlAdapter As SqlDataAdapter Dim dt As New DataTable Dim ds As New DataSet '给cmd 赋值 cmd.CommandText = cmdText cmd.CommandType = cmdType cmd.Connection = conn cmd.Parameters.AddRange(paras) '添加参数 sqlAdapter = New SqlDataAdapter(cmd) '实例化Adapter Try sqlAdapter.Fill(ds) '用adapter将dataset填充 dt = ds.Tables(0) 'datatable是dataset的第一个表 cmd.Parameters.Clear() '清除参数 Catch ex As Exception MsgBox("数据库操作") Finally Call CloseCmd(cmd) '关闭cmd命令 End Try Return dt End Function Public Sub CloseCmd(ByVal cmd As SqlCommand) If Not IsNothing(cmd) Then '如果cmd存在 cmd.Dispose() '销毁 cmd = Nothing End If End Sub End Class
Entity实体
Public Class UserInfo Private _userid As String Private _username As String Private _password As String Private _level As String Public Property userID As String Get Return _userid End Get Set(value As String) _userid = value End Set End Property Public Property userName As String Get Return _username End Get Set(value As String) _username = value End Set End Property Public Property passWord As String Get Return _password End Get Set(value As String) _password = value End Set End Property Public Property level As String Get Return _level End Get Set(value As String) _level = value End Set End Property End Class
遇到的问题
往sqlHelper里传参数时用数组
Public Function ExecSelect(ByVal cmdText As String, ByVal cmdType As CommandType, ByVal paras As ***SqlParameter()***) As DataTable
之前三层时传参数是这样用的
cmd.Parameters.Add(New SqlParameter("@ID", user.ID)) cmd.Parameters.Add(New SqlParameter("@PassWord", user.PSW))
现在把DAL层里连接数据库和公共性的东西抽出来形成sqlHelper。所以要把D层中的sql,parameter等参数都传给sqlHelper,但是parameter中往往有好几个,所以就用到了数组。
找不到指定文件
反射的一个原则:一切皆以UI层的bin文件夹中的dll名称为中心。(原因很简单:.net类加载的机制就是默认从本程序集的bin文件中找,所以bin文件夹中一定要有要加载的程序集的dll)。UI层中bin文件夹中dll叫什么名字AssemblyPath就使用什么名字,bin内部类的全名叫什么,className就写成什么全名。.net中的引用:加入对某个程序集的引用就能在程序集有变化时自动拷贝dll。
以上摘自王雪娜的博客 机房重构七层登录之问题总结
总而言之,各层中的dll名称都以UI层的bin文件里的dLL名称为准,所以方法就是把D层属性里 生成 ——输出路径 改成UI层就OK了。
自己的小想法
我写七层的时候主要借鉴的是同学的博客,并做了一些小改动。同学的B层的返回值类型是datatable,然后在U层把窗体上的密码与table里的密码进行比较。感觉逻辑判断应该放在B层,就把这些判断都写到B层,然后B层和Facade层的返回值类型都是boolean。在U层做判断的时候也做了一些小改动:写了一个嵌套的if语句来判断用户名和密码是不是正确,用户名正确但密码不正确就提示“密码错误”。试了试360 云盘遇到这种情况会给什么提示,它就是提示“密码错误”,感觉这样对用户比较方便。
结语
以前遇到错误心里就犯怵,不过还是在错误中收获最多。这次最欣慰的就是在巨人的肩膀上加上了自己的想法,虽然都是一些简单的想法,但是完全自己设计创造一个东西都是要这样慢慢成长的。不要想太多,像老师说的,做吧,做着做着可能就理解了。在这样的精神指导下,我就要开始机房重构了。相关文章推荐
- 超越Jquery_01_isPlainObject分析与重构
- PHP代码维护,重构变困难的4种原因分析
- Repeater控件动态变更列(Header,Item和Foot)信息(重构cs)
- 重构代码的7个阶段
- 代码整洁之道------它山之玉可以重构:身份证号码解析、验证工具(第一天)
- 它山之玉可以重构:身份证号码解析、验证工具(第二天)
- 它山之玉可以重构:身份证号码解析、验证工具(第三天)
- 重构之重与敏捷之轻---身份证号重构回顾
- 构建者模式之我见
- 编写好代码的10条戒律
- 《重构》
- Scala: 一次命令式到函数式的重构
- 重构-改善既有代码的设计Refactoring - Improving the Design of Existing Code
- Other: 重构—改善既有代码的设计003:代码的坏味道(Bad smells in Code)
- 如果想当一个好的程序猿
- 一段关于重构的小代码
- 《HTML重构》读书笔记&思维导图
- 深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点
- 深入理解JavaScript系列(6):S.O.L.I.D五大原则之单一职责SRP
- 小问题也是大问题