【机房重构】之七层登录不要怕

   【前言】前些日子学习了三层登录,这是我们第一次学习分层的思想。七层只是比三层多增加了几层而且耦合度更加低了,所以我们不用怕一层层的去分析就好啦。

  一、七层的组成

   七层的组成: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


   SQLHelperD层中需要重复使用的连接数据库代码抽象到一个层里面了,这样就不用重复写这些代码了,减少了耦合。这个的代码就单独总结吧。


【总结】刚开始第一遍敲登录的时候完全是参照别人的博客来的,也不是按照一条线的逻辑来敲的,所以虽然最后登陆成功了,但是对于数据是怎么传的还是一头雾水。然后通过之后的整理和请教别人终于把这条线理清楚了,然后按照一条线的顺序实现了登录。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 37
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 37
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值