机房重构——七层登录

刚学了三层,在后来机房重构才知道还有个七层,七层是干嘛的?都有哪七层?为何有个三层,又要转成七层,它的优势在哪?开发大的系统时七层明明代码多了,为何它比三层好用?具体是如何实现的?下面我来为大家依次解答。

七层:

三层有界面显示层(UI),业务逻辑层(BLL)和数据访问层(DAL)。七层不过是比三层多了外观层(Facade),工厂(Factory),接口层(IDAL),加上实体层(Entity)共七层。七层包图如下:

机房重构——七层登录_第1张图片

三层中,UI——>BLL——>DAL,层与层之间通过实体层联系在一起,但是如果我们要做一个大系统,这样很难达到用户需求,层之间的耦合度太高,牵一发而动全身,这就需要用到七层了。这个包图所体现到的设计模式便是外观模式,反射,抽象工厂模式。它所体现的思想便是用户提出需求,我们在U层提出用户需求,通过外观层传递参数,到B层执行业务逻辑处理。

U层主要代码展示:

Entity.LoginEntity.ID = txtUsername.Text.Trim '全局变量
        Try
            Dim Facade As New Facade.LoginFacade
            Dim UserInfo As New Entity.LoginEntity
            UserInfo.UserID = txtUsername.Text.Trim
            UserInfo.Password = txtPassword.Text

            Dim strResult As Boolean
            '将U层的用户信息传入外观层,然后通过外观层传入B层进行判断
            strResult = Facade.CheckUser(UserInfo)

            txtUsername.Text = ""
            txtPassword.Text = ""
            txtUsername.Select()
            txtUsername.Focus()

            Dim table As DataTable
            table = Facade.CheckPwd(UserInfo)

            Me.Hide()
            txtPassword.Text = ""
            txtUsername.Text = ""
            frmMain.Show()
        Catch ex As Exception
            MsgBox("用户不存在或密码不正确")
            txtPassword.Text = ""
            txtUsername.Text = ""
            txtUsername.Select()
            txtUsername.Focus()
        End Try
外观层:传递参数

Public Class LoginFacade
    '检查用户是否存在
    Public Function CheckUser(ByVal UserInfo As Entity.LoginEntity) 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.LoginEntity) As DataTable
        Dim IsPwdExists As New BLL.LoginBLL
        Dim table As DataTable
        table = IsPwdExists.RightPWD(UserInfo)
        Return table
    End Function
End Class
B层:处理业务逻辑:

Imports IDAL

Public Class LoginBLL
    '检查用户是否存在
    Public Function ExistUser(ByVal UserInfo As Entity.LoginEntity) As Boolean
        Dim Factory As New Factory.LoginFactory
        'Dim IUser As IDAL.LoginIDAL
        ''调用创建用户的工厂方法
        'IUser = Factory.CreateIuser '调用工厂的CreatIUser方法创建IUser接口实例
        Dim table As New DataTable '中间变量,用于存储D层查询到的数据
        Dim flag As Boolean
        'table = IUser.selectUser(UserInfo)
        table = Factory.CreateIuser.selectUser(UserInfo)
        If table.Rows.Count = 0 Then
            flag = False
        Else
            flag = True
        End If
        Return flag
    End Function
    '查看密码是否正确
    Public Function RightPWD(ByVal UserInfo As Entity.LoginEntity) As DataTable
        Dim Factory As New Factory.LoginFactory
        Dim IUser As IDAL.LoginIDAL
        Dim table As DataTable '中间变量,用于存储D层查询到的数据

        IUser = Factory.CreateIUser '调用工厂的方法创建Iuser
        table = IUser.selectUser(UserInfo) '调用接口的方法selectUser
        If UserInfo.Password = Trim(table.Rows(0).Item(1)) Then
            MsgBox("登录成功!")
        End If
        Return table
    End Function
End Class
工厂类:将类接口中抽象方法的实体反射给接口:

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

Public Interface LoginIDAL
    '判断用户名是否存在
    Function selectUser(ByVal UserInfo As Entity.LoginEntity) As DataTable
End Interface

由于,对数据库的操作总是重复,大家知道,重复的代码我们都可以将他们封装起来,为减少这样的重复,我在这里增加了SqlHelper类,将所有对数据库的增删改查全部封装进来:

SqlHelper层部分代码:

Public Class SqlHelper
    '数据库连接
    Dim strConnection As String = "Server=wanghongwei;Database=RestructCharge;User ID=sa;Password=123"
    Dim conn As New SqlConnection(strConnection) '建立数据库连接
    Dim cmd As New SqlCommand '定义命令变量cmd

    ''' 
    ''' 执行查询操作,(有参),返回值为datatable类型,参数不限
    ''' 
    ''' 参数cmdTxt为所要执行的sql语句
    ''' 查询时的查询方式
    ''' 查询时的命令参数paras
    ''' 查询后以表的方式返回
    ''' 
    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)   '将结果绑定到数据适配器变量adaptor上面
        Try
            sqlAdapter.Fill(ds)  '用adapter将dataset填充
            dt = ds.Tables(0)   'datatable为dataSet的第一个表 
            cmd.Parameters.Clear()  '清除参数

        Catch ex As Exception
            MsgBox(ex.Message)
        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
最后实体层比较简单,需要用到那个字段就写哪个就可以,但是一定要保持和数据库里定义的数据类型一致,否则就会报错“无法将xx转换为xx类型”。

从以上代码实现我们可以看出,七层很好的分工,使得每层各司其职,这样如果以后我们的系统需要改动,我们只需找到相关的问题,分层解决,既不影响其它层,又完美降低了层与层之间的耦合。

总结:

七层登录是机房重构的开始,是深入了解三层绝好的阶段,万事开头难,但是我相信,只要TO DO,每个人都可以做的很好,所有的过程都会成为美好的回忆,都会成为进阶石,不要在一开始就把自己吓倒,只要坚持做,其实它并不难。






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