《机房收费系统个人版》基本上完工了,我的U层代码很多很乱。基本上是D层有几个函数,B层就对应有几个函数,U层使用对应B层中的每一个函数。比如说在登录中,U层首次要使用一个函数检查用户名和用户密码是否正确,然后再使用“添加用户上机记录”的函数。下面是登录的时序图:
登录业务比较简单,但是对于复杂的上机过程呢?U层要检查卡是否注册,余额是否充足,卡的状态是否在使用中,该卡是否现在不在线,通过这一系列检验后,还要查询学生表显示学生信息等等。这样就造成U层有好多函数,和B层的耦合度太大。现在我们来回顾一下三层中各层的功能:
表现层(UI):采集用户的输入信息和操作,向用户展现特定业务数据。通俗讲就是用户界面,即用户在使用一个系统的时候他的所见所得。
业务逻辑层(BLL):针对具体问题的操作,也可以说是对数据层的操作,对数据业务逻辑处理。主要有三种方式:从UI中获取用户指令和数据,执行业务逻辑;从DAL中获取数据,以供UI显示;从UI中获取用户指令和数据,通过DAL写入数据源。
数据访问层(DAL):该层所做事务直接操作数据库,针对数据的增添、删除、修改、查找等。
在师傅的指点下,进行了修改:
U层:
'登录
Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click
'查空
If PublicFunction.IsEmptyText(Me) = True Then
Exit Sub
End If
'实例化实体User,引用B层
Dim euser As New Entity.User
Dim euserRecord As New Entity.UserRecord
Dim blogin As New BLL.LoginBLL
Try
'将用户输入的信息传给实体
euser.ProuserID = txtUserID.Text.Trim
euser.ProuserPwd = txtUserPwd.Text
'用户验证后反馈信息
If blogin.Check(euser, euserRecord) Then '登录成功
''UserID和UserLevel为全局变量,其他功能要用到
UserID = euser.ProuserID.Trim '去空格
UserLevel = euser.ProuserLevel.Trim '去空格
'主窗体显示
Me.Hide()
frmMain.Show()
Else
MsgBox("登录失败!用户名或密码有误。", vbExclamation, "系统提示")
txtUserID.Focus()
Exit Sub
End If
Catch ex As Exception
MsgBox("错误!", vbExclamation, "系统提示")
End Try
End Sub
B层:
Public Function Check(ByVal euser As Entity.User, ByVal euserRecord As Entity.UserRecord) As Boolean
Dim dt As DataTable
dt = iuser.QueryUser(euser)
Try
If dt.Rows.Count = 0 Then
Return False
Else '用户名和密码输入正确
euser.ProuserID = dt.Rows(0).Item(0) '用户ID
euser.ProuserLevel = dt.Rows(0).Item(2) '用户级别
'输入用户上机记录信息
euserRecord.ProuserID = euser.ProuserID
euserRecord.ProuserLevel = euser.ProuserLevel
euserRecord.ProloginTime = Now
euserRecord.PrologoutTime = Now
euserRecord.ProisOnline = 1 '1表示在线,0表示不在线
euserRecord.Procomputer = My.Computer.Name '获得当前电脑的用户名
'添加用户上机记录
Dim result As Integer
result = iuser.AddUserRecord(euserRecord)
If result <> 0 Then '添加用户记录成功
Return True
End If
End If
Catch ex As Exception
Throw New Exception
End Try
End Function
'查找用户的方法
Public Function QueryUser(euser As Entity.User) As DataTable Implements IUser.QueryUser
Try
Dim strSQL As String = "select * from T_User where userID=@userID and userPwd=@userPwd "
Dim params() As SqlParameter = {New SqlParameter("@userID", euser.ProuserID), New SqlParameter("@userPwd", euser.ProuserPwd)}
Dim helper As New SqlHelper.sqlHelper
Dim table = helper.GetDataTable(strSQL, CommandType.Text, params)
Return table
Catch ex As Exception
Throw New Exception
End Try
End Function
'用户登录成功添加记录到UserRecord
Public Function AddUserRecord(euserRecord As Entity.UserRecord) As Integer Implements IUser.AddUserRecord
'每一个字段都填写时,可省略前面括号中的内容
'Dim strSQL As String = "insert into T_UserRecord values(@userID,@level,@loginTime,@logoutTime,@computer,@isOnline)"
Try
Dim strSQL As String = "insert into T_UserRecord (userID,userLevel,loginTime,logoutTime,computer,isOnline)values(@userID,@level,@loginTime,@logoutTime,@computer,@isOnline)"
Dim params() As SqlParameter = {New SqlParameter("@userID", euserRecord.ProuserID),
New SqlParameter("@level", euserRecord.ProuserLevel),
New SqlParameter("@loginTime", euserRecord.ProloginTime),
New SqlParameter("@logoutTime", euserRecord.PrologoutTime),
New SqlParameter("@computer", euserRecord.Procomputer),
New SqlParameter("@isOnline", euserRecord.ProisOnline)}
Dim helper As New SqlHelper.sqlHelper
Dim intResult = helper.ExecuteNoQuery(strSQL, CommandType.Text, params)
Return intResult
Catch ex As Exception
Throw New Exception
End Try
End Function
修改后的登录时序图:
两幅登录时序图形成鲜明的对比,这样用户点击“登录”按钮后,U层负责采集用户输入的用户名和密码,然后只需调用一个Check()函数进行验证。B层处理业务逻辑,先判断用户信息,若输入正确则进行下一步添加用户上机记录。D层和数据库打交道,进行增删改查。U层根本不知道具体的验证用户细节,这样就解耦了,各司其职。
小结:从去年的第一次机房收费系统,到现在的个人版重构,以及接下来的合作重构,每一步都是跨越。最初我们是纯面向过程的,现在学习了三层架构,使用了设计模式,但距离面向对象仍然很遥远。我们正在一步一步向前走,这个过程很重要,好比是唐僧西天取经,如果让孙悟空翻个跟头就能取到经,那就不会有经典的《西游记》了。