机房重构之七层登陆

       机房重构从登陆开始,由三层框架转向七层非常的不容易,代码一点一点敲上去然后生成解决方案后一层一层地抛错,什么问题都有,好在慢慢都解决了,虽然有的问题自己都不知道怎么就解决了,但是管他呢,慢慢来吧~

       七层框架相比三层,不过是多了外观层(Facade)、工厂层(Factory)和接口层(IDAL),设计模式的应用大大降低了三层架构间的耦合度。七层之间的关系如下:

       下面看一下加入设计模式后的七层架构是怎样的:

        UI层

      U层不再和B层直接交互,而是和外观层进行交互,将用户信息从外观层导入B层进行信息处理,这样在对U层或B层改动时减少互相影响,更好地接触耦合度。

Public Class frmLogin
    Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click
        '输入不能为空
        If txtUserName.Text = "" Then
            MsgBox("请输入用户名", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            txtUserName.Focus()
        End If
        If IsNumeric(txtUserName.Text) = False Then
            MsgBox("用户名请输入数字", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            txtUserName.Text = ""
        End If
        If txtPassword.Text = "" Then
            MsgBox("请输入密码", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            txtPassword.Focus()
        End If

        Try
            Dim Facade As New Facade.LoginFacade
            Dim UserInfo As New Model.LoginUserInfo
            UserInfo.UserName = txtUserName.Text.Trim
            UserInfo.Password = txtPassword.Text
            Dim strResult As Boolean
            '将U层的用户信息传入外观层,然后通过外观层传入B层进行判断
            strResult = Facade.CheckUser(UserInfo)
            If strResult = False Then
                MsgBox("用户不存在", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                txtUserName.Text = ""
                txtPassword.Text = ""
                txtUserName.Select()
                txtUserName.Focus()
            End If
            Dim table As DataTable
            table = Facade.CheckPwd(UserInfo)
            If Trim(txtPassword.Text) = Trim(table.Rows(0).Item(2)) Then
                MsgBox("登陆成功!")
                Me.Hide()
                txtPassword.Text = ""
                txtUserName.Text = ""
            End If
        Catch ex As Exception
            MsgBox("用户不存在或密码不正确")
            txtPassword.Text = ""
            txtUserName.Text = ""
            txtUserName.Select()
            txtUserName.Focus()
        End Try
    End Sub
End Class
        Facade层

      外观层主要是对方法的封装,但还是调用的B层的方法,不过让数据在外观层走一遍。

Public Class LoginFacade
    '检查用户是否存在
    Public Function CheckUser(ByVal UserInfo As Model.LoginUserInfo) As Boolean
        Dim IsUserExists As New BLL.LoginBLL
        Dim flag As Boolean
        flag = IsUserExists.Checkuser(UserInfo)
        If flag = True Then
            Return True
        Else
            Return False
        End If
    End Function
    '检查密码是否正确
    Public Function CheckPwd(ByVal UserInfo As Model.LoginUserInfo) As DataTable
        Dim IsPwdExists As New BLL.LoginBLL
        Dim table As DataTable
        table = IsPwdExists.Checkpwd(UserInfo)
        Return table
    End Function
End Class
         BLL层

      B层进行数据的逻辑处理,返回给外观层处理的信息进行判断,另一方面是接收通过工厂和接口后传来的D层的信息。

Imports IDAL
Public Class LoginBLL
    Public Function Checkuser(ByVal UserInfo As Model.LoginUserInfo) As Boolean
        Dim Factory As New Factory.LoginFactory
        Dim IUser As IDAL.LoginIUserInfo
        '调用创建用户的工厂方法
        IUser = Factory.CreateIUser() '调用工厂的CreatIUser方法创建Iuser接口实例
        Dim table As New DataTable
        Dim flag As Boolean
        table = IUser.selectUser(UserInfo)
        If table.Rows.Count = 0 Then
            flag = False
        Else
            flag = True
        End If
        Return flag
    End Function

    Public Function Checkpwd(ByVal UserInfo As Model.LoginUserInfo) As DataTable
        Dim Factory As New Factory.LoginFactory
        Dim IUser As IDAL.LoginIUserInfo
        Dim table As DataTable

        IUser = Factory.CreateIUser
        table = IUser.selectUser(UserInfo)
        Return table
    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 LoginIUserInfo
        Dim classname As String = "DAL" + "." + strDB + "LoginDAL" '要实例化的D层的类的名称
        Dim IUser As LoginIUserInfo
        'CType函数将返回表达式显示地转换为指定的数据类型、对象、结构、类或接口后的结果
        IUser = CType(Assembly.Load(AssemblyName).CreateInstance(classname), LoginIUserInfo) '返回LoginIUserInfo
        Return IUser
    End Function
End Class
        IDAL层

       接口层用来定义一个统一的接口,解除B层和D层的耦合。

Public Interface LoginIUserInfo
    '判断用户名是否存在
    Function selectUser(ByVal UserInfo As Model.LoginUserInfo) As DataTable
End Interface
        DAL层

      D层用实现接口的方法来实现用户对数据库进行增删改查的操作,与数据库打交道。

Public Class LoginDAL : Implements IDAL.LoginIUserInfo
    '实现接口中的方法
    Private sqlHelper As New SqlHelper.sqlhelper
    '判断用户名是否存在
    Public Function selectUser(UserInfo As LoginUserInfo) As DataTable Implements LoginIUserInfo.selectUser
        Dim sql As String  '中间变量,用于储存从数据库中查找到的信息
        Dim table As DataTable  '声明一个Dat
        '声明并实例化参数数组
        Dim sqlParams As SqlParameter() = {New SqlParameter("@UserName", UserInfo.UserName), New SqlParameter("@Password", UserInfo.Password)}
        sql = "select * from User_info where UserName=@UserName and Password=@Password"
        '调用SqlHelper类中的GetDataTable()方法来执行查询,并获取返回值
        table = sqlHelper.ExecSelect(sql, CommandType.Text, sqlParams)
        Return table
    End Function
End Class
        Entity层

      定义一个实体来封装数据,用以传输。

    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 _password As String
    Public Property Password As String
        Get
            Return _password
        End Get
        Set(value As String)
            _password = value
        End Set
    End Property
End Class
        SqlHelper层

      封装好的增删改查数据库的类。

Imports System.Data
Imports System.Data.SqlClient
Imports System.Configuration
Public Class sqlhelper
    '配置文件
    'Private ReadOnly strConnection As String = ConfigurationSettings.AppSettings("ConnStr")
    '数据库连接
    Dim strConnection As String = "Server=DESKTOP-5KMOCVI;Database=chargejf;User ID=sa;Password=123"
    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

         生成的代码图,和包图差不多,看来代码的大致流程和各层的调用是没错了。

                    

        七层登陆仅仅是个开始,把思路好好梳理清楚,机房重构才不会觉得那么难。加油吧,少年!!

       

你可能感兴趣的:(机房重构之七层登陆)