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

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

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值