三层架构实战篇——抽象工厂+反射实现验证用户登录!

一、“三层”架构就一定要分三层吗?

答案当然是否定的,分层的根本目的就是要达到“高内聚,低耦合”。我们不应该为了分层而分层,那么什么样的分层才是最好的分层呢?我认为,没有最好的分层,只有合理的分层。同时,我们也要根据具体的情况来分析,如果系统很small,不用分层也不是不可。当然,对于一些逻辑复杂的大型系统,分层便显得尤重要了,可以达到所说的,利用团队开发、可复用性、表达的业务逻辑清楚、利于维护等等。

二、下面这个Demo展示实现登录系统的功能,其中利用了抽象工厂+反射+配置文件。

下面是架构图,就是三层架构的扩展,在BLL层与DAL层添加了一个工厂层、接口层。


因为在底层运用了抽象工厂,所以可以方便实现不同数据库的访问。假如,现在要用到的数据库变为Access.就可以把DLL层的SQLServerDAL变成AccessDAL即可。


接下来的类图表现的是其中几个类的关系:

在D层,我添加了一个SQLHelp的类,用来处理SQL语句,与建立连接。代码如下:

    Public MustInherit Class SQLHelper
        Public Shared sConneciton As String = ConfigurationManager.ConnectionStrings("strConnection").ConnectionString
        ''' <summary>
        ''' 执行查询操作
        ''' </summary>
        ''' <param name="connectionString">连接字符串</param>
        ''' <param name="cmdType">commandtype store procedure</param>
        ''' <param name="cmdText">the store procedure name or T-SQL command</param>
        ''' <param name="para">an array of sqlparamters used to execute the command</param>
        ''' <returns>datareader</returns>
        ''' <remarks></remarks>
        Public Shared Function ExecuteDataSet(ByVal connectionString As String, ByVal cmdType As String, ByVal cmdText As String, ByVal para() As SqlParameter) As DataSet
            Dim dbCon As SqlConnection
            Dim dbCmd As SqlCommand
            dbCon = New SqlConnection(sConneciton)
            dbCmd = New SqlCommand
     
            dbCmd.Connection = dbCon
            dbCmd.CommandType = cmdType
            dbCmd.CommandText = cmdText
            dbCmd.Parameters.AddRange(para)
     
            Dim dt As New DataSet
     
            dbCon.Open()    '打开数据库连接
     
            Dim dr As SqlDataReader
            dr = dbCmd.ExecuteReader
            dt.Load(dr, Data.LoadOption.Upsert, "user")
            Return dt
     
            'Dim dataAdapater As SqlDataAdapter
            'dataAdapater = New SqlDataAdapter(dbCmd)
            'dataAdapater.Fill(dt)
            'Return dt
        End Function


下面是DataAccess工厂类,通过接口,确定实例化哪个类。其中用到了反射,为了方便日后数据库维护(只需要将SQLServerDAL类换成AccessDAL类,并用相应的语法实现接口即可。代码如下:

    Public Class DataAccess
        Private Shared db As String = ConfigurationManager.AppSettings("db")       '也要生成为静态的,否则出错
        ''' <summary>
        ''' 获得接口实例
        ''' </summary>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Shared Function CreatUsers() As IUsers
            Dim className As String
            className = db + ".Users"
            Dim result As IUsers
            result = CType(Assembly.Load(db).CreateInstance(className), IUsers)
            Return result
        End Function
    End Class


下面是IUser接口类:

    Public Interface IUsers
     
        ''' <summary>
        ''' 根据userID读取usersinfo
        ''' </summary>
        ''' <param name="strUserID">用户名</param>
        ''' <returns>userinfo</returns>
        ''' <remarks></remarks>
        Function GetUser(ByVal strUserID As String) As UsersInfo
     
     
    End Interface


下面是SQLServerDAL下的Users类(逻辑实体)

    Public Class Users : Implements IUsers
        ''' <summary>
        ''' 取得给定用户名的实体
        ''' </summary>
        ''' <param name="strUserID"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function GetUser(ByVal strUserID As String) As Model.UsersInfo Implements IDAL.IUsers.GetUser
            Dim sql As String
            sql = "select * from Login where userID=@ID"
            Dim dt As New DataSet
            Dim para() As SqlParameter = {New SqlParameter("@ID", strUserID)}
            
     
            dt = SQLHelper.ExecuteDataSet(SQLHelper.sConneciton, CommandType.Text, sql, para)
     
            Dim user As UsersInfo
            user = New UsersInfo(Convert.ToString(dt.Tables(0).Rows(0).Item("userID")), Convert.ToString(dt.Tables(0).Rows(0).Item("Userpassword")))
            Return user
        End Function
    End Class


下面是BLL层的验证类:

    Public Class Verify
        ''' <summary>
        ''' 查询数据库,验证用户是否存在
        ''' </summary>
        ''' <param name="strUserID">传入用户名ID</param>
        ''' <returns>返回查询结果,true or false</returns>
        ''' <remarks></remarks>
        Public Shared Function VerifyUser(ByVal strUserID As String, ByVal strPassWord As String) As Boolean
            Dim user As UsersInfo
            Dim IUser As IUsers
            ' Dim dbAccess As New DataAccess      '工厂用静态的方法,工厂实例化没有意义
     
            IUser = DataAccess.CreatUsers
            '根据给定的UserID查数据库
            user = IUser.GetUser(strUserID)
            '如果根据给定的用户名查到的记录的passwod也相等的话,那么,验证成功,返回true,否则返回false
            If user.PassWord = strPassWord Then
                Return True
            Else
                Return False
            End If
        End Function
    End Class


觉得不妥的地方就是没有例外处理……
欢迎大家交流讨论!

---------------------
作者:yjjm1990
来源:CSDN
原文:https://blog.csdn.net/yjjm1990/article/details/7212374
版权声明:本文为博主原创文章,转载请附上博文链接!

posted @ 2019-05-31 21:04  天涯海角路  阅读(174)  评论(0)    收藏  举报