【前言】前些日子学习了三层登录,这是我们第一次学习分层的思想。七层只是比三层多增加了几层而且耦合度更加低了,所以我们不用怕一层层的去分析就好啦。
一、七层的组成
七层的组成:UI层、Facade层(外观层)、BLL层、Factory层(工厂)、IDAL层(接口)Entity层(实体)
其实还有一个SQLHelper,因为SQLHelper是从DAL层分离出来了,不打算做一层,否则就是8层了。
二、层与层之间的关系
三、各层的作用
UI层:主要是收集用户输入的数据然后传给外观层,这一层是和用户进行交互的,是我们系统的外大门。
Imports Entity.User_InfoEntity
Imports Facade.LoginFacade
Public Class frmLogin
Private Sub Label1_Click(sender As Object, e As EventArgs) Handles Label1.Click
'判断账号是否为空
If txtUserID.Text = "" Then
MsgBox("账号不能为空!")
txtUserID.Focus()
Exit Sub
ElseIf txtPassword.Text = "" Then
MsgBox("密码不能为空!")
txtPassword.Focus()
Exit Sub
End If
Try
'定义一个外观层对象
Dim facadeLogin As New Facade.LoginFacade
Dim UserInfo As New Entity.User_InfoEntity()
'将文本框中的值传给实体层对象让他带上参数
UserInfo.UserID = txtUserID.Text.Trim
UserInfo.Password = txtPassword.Text.Trim
'将U层文本框的内容传入外观曾,然后通过外观层传入B层
Dim strResult As Boolean
strResult = facadeLogin.CheckUser(UserInfo)
If strResult = False Then
MsgBox("用户不存在,请重新输入!")
txtUserID.Text = ""
txtPassword.Text = ""
txtUserID.Focus()
End If
Dim table As DataTable
table = facadeLogin.CheckPWD(UserInfo)
If Trim(txtPassword.Text) = Trim(table.Rows(0).Item(1)) Then
'MsgBox("登录成功!")
'txtUserID.Text = ""
'txtPassword.Text = ""
Dim table2 As DataTable
table2 = facadeLogin.CheckLevel(UserInfo)
If Trim(table2.Rows(0).Item(3)) = "学生" Then
frmMainStu.Show()
ElseIf Trim(table2.Rows(0).Item(3)) = "管理员" Then
frmMain.Show()
ElseIf Trim(table2.Rows(0).Item(3)) = "操作员" Then
frmMain.Show()
frmMain.MainMenuStrip.Items(2).Enabled = False
ElseIf Trim(table2.Rows(0).Item(3)) = "值班教师" Then
frmMain.Show()
frmMain.MainMenuStrip.Items(2).Enabled = False
frmMain.MainMenuStrip.Items(1).Enabled = False
End If
End If
Catch ex As Exception
'MsgBox("用户不存在或密码不正确!")
'txtUserID.Text = ""
'txtPassword.Text = ""
'txtUserID.Select()
'txtUserID.Focus()
MsgBox(ex.Message, , "数据库操作")
End Try
End Sub
End Class
外观层:外观层我们可以联想我们学过的设计模式中的外观模式。还记得我们设计模式书中介绍外观模式的时候运用了基金、股票的例子,如果用户购买基金就不用和所有的股票,债券啥的打交道了,这样就降低了U层和B层之间的耦合,U层和B层之间的联系只需要通过Facade层的接口就行了,U层无需知道B层内部有哪些方法。
外观层接收U层传来的数据,然后调用B层的方法对信息进行验证。
Public Class LoginFacade
'检查用户是否存在
Public Function CheckUser(ByVal UserInfo As Entity.User_InfoEntity) As Boolean
Dim isUserExists As New BLL.LoginBLL()
Dim flag As Boolean
flag = isUserExists.ExistUser(UserInfo)
If flag = True Then
Return True
Else
Return False
End If
End Function
'检查密码是否正确
Public Function CheckPWD(ByVal UserInfo As Entity.User_InfoEntity) As DataTable
Dim isPwdRight As New BLL.LoginBLL()
Dim table As DataTable
table = isPwdRight.RightPWD(UserInfo)
Return table
End Function
'检查用户级别
Public Function CheckLevel(ByVal UserInfo As Entity.User_InfoEntity) As DataTable
Dim isWhichLevel As New BLL.LoginBLL()
Dim table As DataTable
table = isWhichLevel.WhichLevel(UserInfo)
Return table
End Function
End Class
BLL层:BLL层主要是进行逻辑判断的,调用工厂中的方法创建相应的接口。
Imports System.Data.SqlClient
Imports Entity
Imports IDAL
Imports Factory
Public Class LoginBLL
'检查用户是否存在
Public Function ExistUser(ByVal UserInfo As Entity.User_InfoEntity) As Boolean
Dim factory As New Factory.LoginFactory()
Dim Iuser As IDAL.ILoginIDAL
'调用检查用户的工厂方法
Iuser = factory.CheckUserInfo
Dim table As DataTable
Dim flag As Boolean
table = Iuser.selectUser(UserInfo)
If table.Rows(0).Item(0) = 0 Then
flag = False
Else
flag = True
End If
Return flag
End Function
'检查密码是否正确
Public Function RightPWD(ByVal UserInfo As Entity.User_InfoEntity) As DataTable
Dim Factory As New Factory.LoginFactory()
Dim Iuser As IDAL.ILoginIDAL
Dim dt As DataTable
Iuser = Factory.CheckUserInfo
dt = Iuser.selectUser(UserInfo)
Return dt
End Function
'判断用户权限
Public Function WhichLevel(ByVal UserInfo As Entity.User_InfoEntity) As DataTable
Dim factory As New Factory.LoginFactory()
Dim Iuser As IDAL.ILoginIDAL
Dim dt As DataTable
Iuser = factory.CheckUserInfo
dt = Iuser.selectUser(UserInfo)
Return dt
End Function
End Class
Factory层:通过配置文件和抽象工厂我们就可以实现不更改代码,换一下配置文件中的value值就可以更换数据库了。Factory还需要完成的工作就是定义一个接口调用接口层,实现BLL层和DAL层之间的数据传递。
'添加对配置文件的引用
Imports System.Configuration
Imports System.Reflection
Imports IDAL
Imports System.Data
'反射+配置文件+抽象工厂实现数据访问
Public Class LoginFactory
'数据程序集名称、命名空间
Private Shared ReadOnly AssemblyName As String = "DAL"
Dim db As String = System.Configuration.ConfigurationSettings.AppSettings("DB") '配置文件中的名称
Public Function CheckUserInfo() As IDAL.ILoginIDAL
'声明要实例化的D层类的名称,字符串的最终结果是"DAL.SqlserverUserDAL",这里要注意的是相应D层类名即为SqlserverUserDAL
'更改数据库:把配置文件中的add name="DB" value="Sqlserver"的value值改为"Access",则不需更改程序,只需更改配置文件的value值,即可实例化D层一个新的类AccessUserDAL
'Dim classroom As String = AssemblyName + "." + db + "DAL"
Dim className As String = db + "." + "LoginDAL"
'将实例化的D层类通过向上转型转换成接口类,然后通过调用接口类中的函数来调用D层中实现该接口的函数。
Return CType(Assembly.Load(AssemblyName).CreateInstance(className), IDAL.ILoginIDAL)
'CType函数将返回表达式显示地转换为指定的数据类型、对象、结构、类或接口后的结果
End Function
End Class
IDAL层:定义接口
Imports System.Reflection
Imports Entity.User_InfoEntity
Public Interface ILoginIDAL
'定义查找用户的方法,用于在数据库中查找用户
Function selectUser(ByVal UserInfo As Entity.User_InfoEntity) As DataTable
End Interface
DAL层:实现接口层定义的接口
Imports System.Reflection
Imports IDAL
'SQL Server 的 .NET Framework 数据提供程序。
Imports System.Data.SqlClient
'提供对表示 ADO.NET 结构的类的访问。
Imports System.Data
Imports Entity
Imports SQLHelper
Public Class LoginDAL : Implements IDAL.ILoginIDAL
'实现接口中定义的方法
Public Function selectUser(UserInfo As User_InfoEntity) As DataTable Implements ILoginIDAL.selectUser
Dim sqlhelper As New SQLHelper.sqlhelper
Dim cmdType As CommandType = New CommandType()
Dim sqlParams As SqlParameter() = {New SqlParameter("@UserID", UserInfo.UserID), New SqlParameter("@Password", UserInfo.Password)}
Dim cmdText As String
cmdText = "select * from User_Info where UserID=@UserID and Password=@Password"
Dim dt As New DataTable
dt = sqlhelper.ExcuteSelect(cmdText, CommandType.Text, sqlParams)
Return dt
End Function
End Class
Entity层:和三层中的实体层一样,主要是用来在各层中传递数据。
Public Class User_InfoEntity
'定义用户ID
Private _userID As String
Public Property UserID As String
Get
Return _userID
End Get
Set(value As String)
_userID = value
End Set
End Property
'定义密码
Private _password As String
Public Property Password As String
Get
Return _password
End Get
Set(value As String)
_password = value
End Set
End Property
'定义用户名
Private _username As String
Public Property UserName As String
Get
Return _username
End Get
Set(value As String)
_username = value
End Set
End Property
'定义级别
Private _level As String
Public Property Level As String
Get
Return _level
End Get
Set(value As String)
_level = value
End Set
End Property
'定义注册时间
Private _redate As Date
Public Property ReDate As String
Get
Return _redate
End Get
Set(value As String)
_redate = value
End Set
End Property
'定义开户人
Private _head As String
Public Property Head As String
Get
Return _head
End Get
Set(value As String)
_head = value
End Set
End Property
End Class
SQLHelper:将D层中需要重复使用的连接数据库代码抽象到一个层里面了,这样就不用重复写这些代码了,减少了耦合。这个的代码就单独总结吧。
【总结】刚开始第一遍敲登录的时候完全是参照别人的博客来的,也不是按照一条线的逻辑来敲的,所以虽然最后登陆成功了,但是对于数据是怎么传的还是一头雾水。然后通过之后的整理和请教别人终于把这条线理清楚了,然后按照一条线的顺序实现了登录。