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

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

答案当然是否定的,分层的根本目的就是要达到“高内聚,低耦合”。我们不应该为了分层而分层,那么什么样的分层才是最好的分层呢?我认为,没有最好的分层,只有合理的分层。同时,我们也要根据具体的情况来分析,如果系统很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

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

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值