加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

VB.NET版的“8层”用户登录实例

发布时间:2020-12-17 00:12:41 所属栏目:大数据 来源:网络整理
导读:做完了三层以后由于期末考试准备专业课考试,就放弃研究三层了,结果就是开学以后都忘了!怎么办?重新学呗!就这样开启了我的研究八层之旅,想着如果把这8层弄好了,以后的机房重构肯定会轻松一点! 首先,先放上我的一张类图: 看了这张类图就有人问了,这
做完了三层以后由于期末考试准备专业课考试,就放弃研究三层了,结果就是开学以后都忘了!怎么办?重新学呗!就这样开启了我的研究八层之旅,想着如果把这8层弄好了,以后的机房重构肯定会轻松一点!
首先,先放上我的一张类图:

看了这张类图就有人问了,这不是一共7个包吗?何来的8层?其实我的8层只是在7层的基础上添加了一个sqlHelper类作为一层,关于这个类的增加还是我的师傅的博客给了我提醒:http://www.52php.cn/article/p-umkuuzkg-wa.html。其实写完这个第8层,我也不知道这个类到底是用来干什么的,只知道它是用来简化D层查询数据库语句的重复代码的!

其他7层的关系,听我细细道来:首先这个7层其实就是在三层的基础上再次对U层、B层、D层进行解耦!因为如果正常的三层的话,U层会调用B层的方法,而B层会调用D层的方法,这样的调用其实不是真正的解耦,因为一点B层或者D层有改动,那么U层也就会跟着改动,这就违反了开放-封闭原则。
所以我们就在U层和B层之间添加一个外观的类,让B层的变化不会影响U层,甚至U层都不用知道B层的存在就可以完成它的功能。在B层和D层之间添加这个接口类也是这个道理,让接口中只有方法,至于这个方法的具体怎么完成都写在了D层。至于添加抽象工厂类,是为了如果这个系统更换数据库方便。

那么先让我们依次来看看每层的代码:

接口层:

Imports LoginEntity
Public Interface IuserinfoDAL
    'UserInfo为用户信息的实体,是由实体类实例化来的。
    '即所谓的传实体。
    '此接口定义了一个方法,用以检查用户是否存在
    Function selectUser(ByVal UserInfo As LoginUserEntity) As DataTable
End Interface


D层:

Imports System.Data.SqlClient 'System.Data.SqlClient 命名空间是 SQL Server 的 .NET Framework 数据提供程序。
'SQL Server 的 .NET Framework 数据提供程序描述了一个类集合,这个类集合用于访问托管空间中的 SQL Server 数据库。
Imports LoginEntity
Imports IDAL
'Imports System.Configuration '对配置文件的引用
Imports SQLHelper
Public Class LoginUserDAL : Implements IDAL.IuserinfoDAL '实现接口中的方法。
    '声明并实例化SQLHelper类
    Private SqlHelper As SQLHelper.sqlHelper = New SQLHelper.sqlHelper()
    

    Public Function selectUser(UserInfo As LoginUserEntity) As DataTable Implements IuserinfoDAL.selectUser
        Dim Sql As String
        Dim table As DataTable '中间变量,用于储存从数据库中查找到的信息                                                         '声明一个DataTable类型变量  
        Dim sqlParams As SqlParameter() = {New SqlParameter("@UserName",UserInfo.userName),New SqlParameter("@password",UserInfo.password)} '声明并实例化参数数组 
        Sql = "select * from Users where UserName=@UserName and Password=@password"
        '下句为调用SqlHelper类中的GetDataTable()方法来执行查询,并获取返回值
        table = SqlHelper.GetDataTable(Sql,CommandType.Text,sqlParams)
        Return table
    End Function
End Class  




sqlHelper类:

Imports System.Data.SqlClient
Imports System.Configuration
Imports System.Data
Public Class sqlHelper
    Private Shared ConnectionString As String = ConfigurationManager.AppSettings("ConnString")
    ''' <summary>
    ''' 执行带参数的查询操作
    ''' </summary>
    ''' <param name="cmdTxt">参数cmdTxt为所要执行的sql语句</param>
    ''' <param name="cmdType">查询时的查询方式</param>
    ''' <param name="paras">查询时的命令参数paras</param>
    ''' <returns>查询后以表的方式返回,如下面的adataset.Tables(0)</returns>
    ''' <remarks></remarks>
    Public Shared Function GetDataTable(ByVal cmdTxt As String,ByVal cmdType As CommandType,ByVal paras As SqlParameter()) As DataTable
        Dim conn As SqlConnection = New SqlConnection(ConnectionString) '建立数据库连接
        Dim cmd As SqlCommand '定义命令变量cmd
        Dim adaptor As SqlDataAdapter '定义数据适配器
        Dim adataset As DataSet '定义并实例化数据缓冲区对象,即从数据库传入的对象。
        cmd = New SqlCommand(cmdTxt,conn) '在conn上面执行实例化命令变量,并执行语句cmdType
        cmd.CommandType = cmdType '命令执行的类型
        cmd.Parameters.AddRange(paras) '命令执行时的参数
        adaptor = New SqlDataAdapter(cmd) '将结果绑定到数据适配器变量adaptor上面
        adataset = New DataSet
        Try
            '如果数据库连接状态为关闭则将其打开
            If conn.State = ConnectionState.Closed Then
                conn.Open()
            End If
            adaptor.Fill(adataset) '向adaptor对象中填充查询的数据
        Catch ex As Exception
            '错误处理程序,出错则提示
            MsgBox(ex.Message,"数据库操作")
        Finally
            '如果连接状态为打开则将其关闭,释放内存
            If conn.State = ConnectionState.Open Then
                conn.Close()
            End If
        End Try
        '以表格形式返回结果
        Return adataset.Tables(0)
    End Function
End Class



B层:

Imports Factory
Imports IDAL
Imports LoginEntity
Public Class LoginBLL
    '检查用户是否存在
    Public Function IsUserExists(ByVal UserInfo As LoginEntity.LoginUserEntity) As Boolean
        Dim factory As New Factory.LoginFactory()
        Dim Iuser As IDAL.IuserinfoDAL
        '调用"创建用户"的工厂方法
        Iuser = factory.CreateUserInfo()
        Dim table As DataTable
        Dim flag As Boolean
        table = Iuser.selectUser(UserInfo)
        '由于在sqlHelper中返回的形式为表格形式(adataset.Tables(0)),且开头第一列表示为0,所以Item(0)则代表用户名
        If table.Rows(0).Item(0) = 0 Then
            flag = False
        Else
            flag = True
        End If
        Return flag
    End Function
    '查看密码是否正确
    Public Function isPWDright(ByVal UserInfo As LoginEntity.LoginUserEntity) As DataTable
        Dim factory As New Factory.LoginFactory()
        Dim Iuser As IDAL.IuserinfoDAL
        Dim table As DataTable   '中间变量,用于存储D层查询到的数据  
        Iuser = factory.CreateUserInfo   '调用工厂的CreateUserInfo方法创建Iuser接口实例  
        table = Iuser.selectUser(UserInfo)  '调用接口的方法selectUser.  
        Return table
    End Function
End Class




外观类:

Imports LoginBLL
Imports LoginEntity
Public Class LoginFacade
    Public Function CheckUser(ByVal UserInfo As LoginEntity.LoginUserEntity) As Boolean
        '用于检查用户是否存在  
        Dim IsUserExists As New LoginBLL.LoginBLL()
        Dim flag As Boolean
        flag = IsUserExists.IsUserExists(UserInfo)
        If flag = True Then
            Return True
        Else
            Return False
        End If
    End Function
    '检查密码是否正确  
    Public Function CheckPwd(ByVal UserInfo As LoginEntity.LoginUserEntity) As DataTable
        Dim IsPwd As New LoginBLL.LoginBLL()
        Dim table As DataTable
        table = IsPwd.isPWDright(UserInfo)
        Return table
    End Function
End Class




U层:
Imports LoginBLL
Imports LoginEntity
Imports Facade
Public Class Form1
    Private Sub btnLogin_Click(sender As Object,e As EventArgs) Handles btnLogin.Click
        If txtBox1.Text = "" Then
            MessageBox.Show("请输入用户名!","",MessageBoxButtons.OK,MessageBoxIcon.Exclamation)
            txtBox1.Text = ""
            txtBox1.Focus()
            Exit Sub
        ElseIf txtBox2.Text = "" Then
            MessageBox.Show("请输入密码!",MessageBoxIcon.Exclamation)
            txtBox2.Text = ""
            txtBox2.Focus()
            Exit Sub
        End If
        Try
            '定义一个外观层的对象  
            Dim FacadeLogin As New Facade.LoginFacade
            Dim UserInfo As New LoginEntity.LoginUserEntity()
            UserInfo.userName = txtBox1.Text
            UserInfo.password = txtBox2.Text
            Dim strResult1 As Boolean
            strResult1 = FacadeLogin.CheckUser(UserInfo) '将U层的文本框的内容传入外观层,然后通过外观层传入B层进行判断
            If strResult1 = False Then
                MsgBox("用户不存在!")
                txtBox1.Text = ""
                txtBox2.Text = ""
                txtBox1.Select()
                txtBox1.Focus()
            End If
            Dim table As DataTable
            table = FacadeLogin.CheckPwd(UserInfo)
            If Trim(txtBox2.Text) = Trim(table.Rows(0).Item(2)) Then
                MsgBox("登陆成功!")
                txtBox1.Text = ""
                txtBox2.Text = ""
            End If
        Catch ex As Exception
            MsgBox("用户不存在或者密码不正确")
            txtBox1.Text = ""
            txtBox2.Text = ""
            txtBox1.Select()
            txtBox1.Focus()
        End Try
    End Sub
End Class


工厂类:

Imports System.Configuration    '添加对配置文件的引用  
Imports System.Reflection       '添加对反射的引用  
Imports IDAL
Public Class LoginFactory
    '读配置文件,D层的每个类都在配置文件里对应一个KEY
  '下面这句是把key设成变量,然后再下面的方法中只用这个变量就可以应用D层的这个类了。
  Dim strDB As String = System.Configuration.ConfigurationSettings.AppSettings("strDB")
  Public Function CreateUserInfo() As IuserinfoDAL
    'CType是一个内联函数,将前部分的表达式转换为后面的类型
    Return CType(Assembly.Load("LoginDAL").CreateInstance("LoginDAL" & "." & strDB),IuserinfoDAL)   '返回IuserinfoDAL
  End Function
End Class

实体类:

Public Class LoginUserEntity
    Private strUserName As String  '实例化得到的用户名和密码
    Private strPassword As String
    Public Property userName() As String  '设置userName的属性
        Get
            Return strUserName
        End Get
        Set(value As String)
            strUserName = value
        End Set
    End Property
    Public Property password() As String
        Get
            Return strPassword
        End Get
        Set(value As String)
            strPassword = value
        End Set
    End Property
End Class


小结:

其实不管是几层,都是为了类之间的解耦,为了满足软件的那六个原则,同时也是为了让代码简单一点。可以让自己设计的软件的灵活性更高,便于维护和测试!
这次研究7层虽然还不很明白sqlHelper类是什么作用,但是数据在各层之间怎么传递感觉又明白了不少,挺有收获的。师傅说把7层弄懂,重构就会简单一点,看来真的是不错,现在不怎么害怕重构了。希望自己的重构之路能够更加顺利一点。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读