【.NET机房重构】——再看抽象工厂加反射实现登录

    纯三层的机房重构终于敲完了,但是还需要加设计模式,这又是一道难题。研究了半天的时间,终于对七层的运行步骤熟悉了一些,也对抽象工厂加反射和配置文件了解的更多了一些,下面就看看我的新认识。



    这是七层的包图,说是七层,但是七层并不是严格意义上的七层,只不过在三层的基础上加上了工厂、外观和接口,用到设计模式的地方多了自然就形成了一层,所以就有了现在的七层。


各层代码

界面层

    分层之后界面层的功能很简单,不能再有逻辑判断,可以有些简单的是否为空或者是否为数字等。

<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;">Public Class frmLogin
    ''' <summary>
    ''' 登录
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click
        Dim lFac As New Facade.loginFac
        Dim result As String
        Dim User As New Entity.UserInfo
        User.ID = txtID.Text.Trim
        User.Password = txtPwd.Text.Trim
        result = lFac.Confirm(User)
        Select Case result
            Case "该用户不存在!"
                txtID.Focus()
                txtID.SelectAll()
            Case "密码错误!"
                txtPwd.Focus()
                txtPwd.SelectAll()
            Case "登录成功!"
                MsgBox("登录成功!")
        End Select
    End Sub

End Class</span></span></span></span>


外观层

    我理解的外观层其实放的是U层需要用到的方法,这样U层就只跟外观层打交道就好了,它不需要知道具体实现,这样就很好的做到了解耦。

<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;">Public Class loginFac
    ''' <summary>
    ''' 验证用户
    ''' </summary>
    ''' <param name="User"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Confirm(ByVal User As Entity.UserInfo) As String
        Dim ConfirmUser As New BLL.LoginBLL
        If Not ConfirmUser.IsExist(User) Then
            Return "该用户不存在!"
        Else
            If Not ConfirmUser.ConfirmPwd(User) Then
                Return "密码错误!"
            Else
                Return "登录成功!"
            End If
        End If
    End Function
End Class</span></span></span></span>


逻辑判断层

    逻辑判断层顾名思义,就是进行逻辑判断的,登录时的判断用户是否存在和密码输入是否正确就在B层进行判断。

<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;">Public Class LoginBLL
    ''' <summary>
    ''' 验证用户是否存在
    ''' </summary>
    ''' <param name="User"></param>
    ''' <returns>布尔值</returns>
    ''' <remarks></remarks>
    Public Function IsExist(ByVal User As Entity.UserInfo) As Boolean
        Dim IUser As IDAL.IUserInfo
        Dim factory As New Factory.DataAccess

        IUser = factory.CreateUserInfo()
        If IUser.SelectUser(User)(0).ID = "" Then
            Return False
        Else
            Return True
        End If
    End Function
    ''' <summary>
    ''' 验证密码是否正确
    ''' </summary>
    ''' <param name="User"></param>
    ''' <returns>布尔值</returns>
    ''' <remarks></remarks>
    Public Function ConfirmPwd(ByVal User As Entity.UserInfo) As Boolean
        Dim IUser As IDAL.IUserInfo
        Dim factory As New Factory.DataAccess

        IUser = factory.CreateUserInfo()
        If IUser.SelectUser(User)(0).Password = "" Then
            Return False
        Else
            Return True
        End If
    End Function
End Class</span></span></span></span>


接口

    接口是定义一个方法名,为了让D层去实现,我觉得接口的存在也很好的做到了解耦,在B层就只需要声明一个接口,具体实现也不需要了解。

<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;">Public Interface IUserInfo
    Function SelectUser(ByVal User As Entity.UserInfo) As List(Of Entity.UserInfo)
End Interface</span></span></span></span>


工厂

    工厂的功能就是批量的产生类,就像现实中的工厂,给了订单之后,就可以批量生产。其实接口和工厂就像现实生活中的老板和工厂,老板是联系顾客和工厂的中介,接口也同样。

<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;">Public Class DataAccess
    Dim strDB As String = System.Configuration.ConfigurationSettings.AppSettings("DB")
    ''' <summary>
    ''' 产生类
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function CreateUserInfo() As IDAL.IUserInfo
        Return CType(Assembly.Load("DAL").CreateInstance("DAL.LoginDAL"), IDAL.IUserInfo)
    End Function
End Class</span></span></span></span>


数据层

    D层主要是和数据库打交道,将你想要的信息查询出来并返回,或者按照你的意愿更新数据库的信息,也就是数据库的增删改查。

<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;">Public Class LoginDAL : Implements IDAL.IUserInfo
    ''' <summary>
    ''' 查询Users表的信息
    ''' </summary>
    ''' <param name="User"></param>
    ''' <returns>泛型集合</returns>
    ''' <remarks></remarks>
    Public Function SelectUser(ByVal User As Entity.UserInfo) As List(Of Entity.UserInfo) Implements IDAL.IUserInfo.SelectUser
        Dim helper As New SQLHelper
        Dim sql As String = "Select * From Users Where ID = '" & User.ID & "'"
        Dim dt As New DataTable
        Dim lUser As New List(Of Entity.UserInfo)
        dt = helper.ExecuteSelect(sql, CommandType.Text)
        lUser = ConvertHelper.ConverToList(dt, lUser)
        Return lUser
    End Function
End Class</span></span></span></span>


利用反射换数据库

       Assembly.Load("程序集名称").CreateInstance("命名空间.类名称")

    程序集名称就是类库属性中的程序集名称,命名空间就是类库属性中的根命名空间,类名称就是该命名空间下的类名。利用反射换数据库的实质其实就是,如果要使用不同的数据库,D层就应该有不同的类,比如用Sql Server时类名为LoginDALSql,用Oracle时类名应该为LoginDALOra。因为数据库类型可以用配置文件中的字符串来变动,所以在配置文件中需这样写:

<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"><?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="strConn" value="Server=localhost;DataBase=Login;User=sa;Password=0722"/>
    <add key="DB" value="Sql"/>
  </appSettings>
</configuration></span></span></span></span>


然后工厂中的代码为

<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;">Public Class DataAccess
    Dim strDB As String = System.Configuration.ConfigurationSettings.AppSettings("DB")
    ''' <summary>
    ''' 利用反射
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function CreateUserInfo() As IDAL.IUserInfo
        Return CType(Assembly.Load("DAL").CreateInstance("DAL.LoginDAL" & strDB), IDAL.IUserInfo)
    End Function
End Class</span></span></span></span>

    “DB”是读取的配置文件中的字符串,strDB是定义的换数据库的字符串,这样工厂返回的类名应该是“DAL.LoginDALSql”。如果要换数据库,只需要将配置文件的“Sql”换成“Ora”就行了,工厂返回的类名就是“DAL.LoginDALOra”,这样就可以实现不同数据库操作类的更换。


遇到的错误

登录中主要遇到了两个问题:

1、未能加载文件或程序集“DAL”或它的某一个依赖项。系统找不到指定文件

    这个错误参照李社河师哥的一篇博客解决的:解决方法参考

2、配置系统未能初始化

    这个问题网上有很多解决方法,其实最主要的原因就是配置文件写错了,可能是顺序错误或者什么的。我出现的错误是大小写的问题,应该写成大写的写成了小写,就这样就酿成了悲剧。



配置文件

    在机房重构中主要用配置文件其实就是写数据库连接字符串,写配置文件时有一个顺序要求,configSections-->connectionStrings-->appSettings,

<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"><?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
      <section name ="" type =""/>
    </configSections>
    <connectionStrings>
        <add name="" connectionString="" providerName="" />
    </connectionStrings>
    <appSettings>
      <add key="" value =""/>
    </appSettings>
</configuration></span></span></span>
上面是一个空的配置文件,只有加载格式没有内容。三者的顺序必须按照上面的前后顺序,否则也会出现“配置系统未能初始化”的错误。这三种方式都可以写连接数据库的字符串,只不过效果不太一样。比如,ConnectionStrings可以将连接数据库的字符串加密等等。另外,用不同的方式写连接字符串,读取配置文件的代码不同,如果用AppSettings写,代码就是

<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;">System.Configuration.ConfigurationSettings.AppSettings("")</span></span>
如果用ConnectionStrings来写的话,代码是

<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;">System.Configuration.ConfigurationSettings.ConnectionStrings("")</span></span>


需要的代码资源,可下载:七层登录实现


总结

    对于自己学的东西,不管是什么东西,都要先着手去做,开始的时候不知道该怎么做,可能改了又改,可是就是这个过程才能让自己对它理解更深。另外,学什么东西不要只看到表面,不理解深层,这样容易卡在一个小问题上。





评论 121
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值