机房重构之七层登录

来源:互联网 发布:mac键盘部分按键失灵 编辑:程序博客网 时间:2024/05/16 14:36

七层登录是机房重构的基础。
对于机房重构来说,七层基本每条线都会使用。学会七层会有很大的便利。
1.什么是七层
其实七层还是以三层为基础,做的一种拓展,目的依旧是为了解耦,采用两个设计模式,使三层拓展为七层,达到松耦合的目的。
七层:除了最基本的U、B、D三层外,包含一个接口层、一个工厂层、一个外观层。和一个最基本的实体层。
工厂层和外观层就是采用设计模式后添加的内容。
2.我七层的思路。
最初的时候,做七层的时候,就是从网上当代码,然后敲。但是在后期挑错的时候发现好多的内容并不是通的。缺斤少两,而且不懂其中的意思。
所以决定自己来做七层!
首先拿过来我的三层。三层学习内容比较简单。然后在三层的基础上添加一个外观层。
外观层在U、B两层之间。解两层之间的耦合,过程依旧很简单。
建立一个Facade类,然后在当中添加一个方法。

Public Class UserFacade

    '检查用户是否存在
    Public Function CheckUser(ByVal enUser As Entity.UserEntity) As Boolean

    End Function

End Class
然后在外观层中实例化B层,
  Dim IsUserExist As New BLL.UserBLL


在UI层实例化外观层,实现解耦
Dim FacodeLogin As New Facade.UserFacade


然后自然的在外观层中添加方法。
还是一个传参的过程



    Public Function CheckUser(ByVal enUser As Entity.UserEntity) As Boolean
        Dim result As Boolean
        result = IsUserExist.CheckUser(enUser)
        Return result
    End Function
Public Interface IUser
    '检查用户是否存在和密码是否正确
    Function SelectExistUser(ByVal enUser As UserEntity) As Boolean



这样三层+实体层+外观层就已经是五层了,剩下的两层,一个接口层,一个工厂层、
D层实现接口,
先创建一个接口




Public Class UserDAL : Implements IUser
    Public Function SelectExistUser(ByVal enUser As UserEntity) As Boolean Implements IUser.SelectExistUser


    End Function
End Class




D层依旧是连接数据库,放与数据库有关的内容。三层中的内容基本不用改
然后处理最后一个工厂层
在最初的时候会有疑惑,为什么要有一个工厂层,没有行不行,感觉他好难啊。
然后在一系列的思考后有了如下的见解。
工厂的作用:就像《大话设计模式》里边的例子一样,方便后期的数据库更换,如果最初采用SQL server数据库但是后期如果换数据库的话
代码就需要大批量的修改,一定程度上违背了开闭原则。所以采用抽象工厂模式,
在抽象工厂模式中比价复杂的地方就在于反射的实现。
在说反射之前,必须要说一下配置文件。因为如果要用到反射的话,那么久一定要用配置文件,在配置文件中存放数据库

  <appSettings>
    <add key="DB"  value="sql"/>
    <add key="yu"  value="DAL"/>
  </appSettings>


在配置文件中添加一定的内容,目的依旧是上边说的,然后建立工厂层,
在使用反射时,必须要做引用命名空间的过程。


首先要先添加引用,然后再引用命名空间

Imports System.Reflection
Imports System.Configuration


反射的格式在书上写的很清楚。
Assembly.load("程序集名称").CreateInstance("命名空间.类名称")
然后只需要在工厂层中添加就可以了


    '利用反射+配置文件+抽象工厂


    Private Shared ReadOnly AssemblyName As String = ConfigurationManager.AppSettings("yu") '定义程序集名称变量,D层命名空间的名字
    'Dim strDB As String = ConfigurationManager.AppSettings("DB") '表示读取配置文件

    '创建用户表的工厂

    Public Function CreateUserInfo() As IDAO.IUser
        Dim className As String = AssemblyName + "." + "UserDAL"
        'AssemblyName是程序集的名称,db+UserDAL是DAL层中的SQLServerUserDAL的类名,
        '之所以配置文件中写SQLserver,是因为D层中类名是SqlServerUserDAL.
        '如果不用SQLserver数据库,那么就在factory中再建一个类,比如访问Access数据库,那么类名就叫做AccessUserDAL
        Return CType(Assembly.Load(AssemblyName).CreateInstance(className), IUser)



最后一句话是一个类型转换的问题。
配置文件为什么要放在U层,这也是一个问题,大家是否有思考?
因为程序在最初启动的时候首先调用UI层,放到U层在程序启动的时候就一并使用了配置文件。


工厂层其实代码很少,就只有两行,第一步读取配置文件,第二步反射。
这样七层就基本完成了,但是还缺一些完善。U层通过Facade层解耦,D层实现接口,就只剩下B层没有动过,接下来整理B层
B层要连接工厂层和接口层,这样七层才能在意义上连通。
首先就是实例化工厂
然后连接接口
接着,传参数,
设置返回值。

    Public Function CheckUser(ByVal enUser As Entity.UserEntity) As Boolean
        Dim Fac As New FacatoryUser
        Dim IUser As IUser
        '调用创建用户的工厂方法
        Dim Result As Boolean
        IUser = Fac.CreateUserInfo()
        Result = IUser.SelectExistUser(enUser)
        Return Result
    End Function




这样七层就从三层拓展到了七层。这只是我个人的思路。
大致上就理通了,然后就是各层间的引用问题
从UI层开始
UI层引用实体层+Facade层
Facade层引用实体层+B层
B层引用实体层+工厂层+接口层
工厂层引用实体层+接口层
接口层引用实体层
D层引用实体层+接口层
然后会发现,D层没有任何一层“”引用”他,翻看文件夹中U层文件夹bin\debug\文件夹中没有D层的文件
那么在运行的时候就会出错。


解决方案很简单,

右键D层属性,打开编译页,生成文件路径改一下就可以了
改到UI层\bin\debug文件夹中就可以了


或许有人会问为什么不使用SQLhelper类?
对于我个人来说:
首先要明白为什么要使用SQLhelper类:因为在重构过程
中D层的代码大部分都是重复的,所以抽象化出来一个SQLhelper类
存放重复的代码。减少代码的冗余。
但是目前只涉及到了一个登陆的问题,所以没有必要涉及一个新的类。

接下来各层的代码:

UI层

Imports System.DataImports SystemImports EntityImports FacadePublic Class Form1    Private Sub ButOK_Click(sender As Object, e As EventArgs) Handles ButOK.Click        '实例化需要的类        Dim enuser As New Entity.UserEntity        'Try        enuser.userID = TxtUserName.Text.Trim()        enuser.PassWord = TxtPassWord.Text.Trim()        Dim FacodeLogin As New Facade.UserFacade        Dim strResult As Boolean        '将U层的用户信息传给外观层        strResult = FacodeLogin.CheckUser(enuser)        If strResult = False Then            MsgBox("用户名不存在,请核对后输入", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)            TxtUserName.Text = ""            TxtPassWord.Text = ""            TxtUserName.Select()            TxtUserName.Focus()        End If        Dim table As Boolean        table = FacodeLogin.CheckPassWord(enuser)        If table = True Then            MsgBox("登录成功!")        End If    End SubEnd Class

 

Facade层

Imports BLLImports EntityPublic Class UserFacade    '因为调用B层的方法,所以过程其实差不多    Dim IsUserExist As New BLL.UserBLL    '检查用户是否存在    Public Function CheckUser(ByVal enUser As Entity.UserEntity) As Boolean        Dim result As Boolean        result = IsUserExist.CheckUser(enUser)        Return result    End Function    '检查密码是否正确    Public Function CheckPassWord(ByVal enUser As Entity.UserEntity) As Boolean        Dim Table As Boolean        Dim isPwdExist As New BLL.UserBLL        Table = isPwdExist.CheckPassWord(enUser)        Return Table    End FunctionEnd Class

 

B层

Imports IDAOImports EntityImports FacatoryPublic Class UserBLL    '检查用户是否存在    Public Function CheckUser(ByVal enUser As Entity.UserEntity) As Boolean        Dim Fac As New FacatoryUser        Dim IUser As IUser        '调用创建用户的工厂方法        Dim Result As Boolean        IUser = Fac.CreateUserInfo()        Result = IUser.SelectExistUser(enUser)        Return Result    End Function    '判断用户登录密码是否正确的逻辑    Public Function CheckPassWord(ByVal enUser As Entity.UserEntity) As Boolean        Dim factory As New Facatory.FacatoryUser        Dim Iuser As IDAO.IUser        Dim table As Boolean        Iuser = factory.CreateUserInfo        table = Iuser.SelectExistUser(enUser)        Return table    End FunctionEnd Class

 

Facatory层

Imports System.ReflectionImports System.ConfigurationImports IDAOImports System.Data.DataTablePublic Class FacatoryUser    '利用反射+配置文件+抽象工厂    Private Shared ReadOnly AssemblyName As String = ConfigurationManager.AppSettings("yu") '定义程序集名称变量,D层命名空间的名字    'Dim strDB As String = ConfigurationManager.AppSettings("DB") '表示读取配置文件    '创建用户表的工厂    Public Function CreateUserInfo() As IDAO.IUser        Dim className As String = AssemblyName + "." + "UserDAL"        'AssemblyName是程序集的名称,db+UserDAL是DAL层中的SQLServerUserDAL的类名,        '之所以配置文件中写SQLserver,是因为D层中类名是SqlServerUserDAL.        '如果不用SQLserver数据库,那么就在factory中再建一个类,比如访问Access数据库,那么类名就叫做AccessUserDAL        Return CType(Assembly.Load(AssemblyName).CreateInstance(className), IUser)        '将实例化D层类通过向上转型转换为接口类,然后通过调用接口类中的函数来调用D层中实现该接口的函数    End FunctionEnd Class

 

IUser层

Imports EntityImports System.Data.DataTablePublic Interface IUser    '检查用户是否存在和密码是否正确    Function SelectExistUser(ByVal enUser As UserEntity) As BooleanEnd Interface

 

D层

Imports EntityImports System.Data.SqlClientImports System.DataImports IDAOPublic Class UserDAL : Implements IUser    Public Function SelectExistUser(ByVal enUser As UserEntity) As Boolean Implements IUser.SelectExistUser        '连接数据库        Dim sqlCon As SqlConnection        Dim strConnect As String = "data source=WZW;initial catalog=Login;user id=SA;password=123456;"        sqlCon = New SqlConnection(strConnect)        Dim table As Boolean    '定义变量,用于存储执行的结果并返回        '将sql语句写在存储过程“adminvaild”中,然后引用存储过程        Dim str As String = "adminVaild"        '采用参数化查询数据,防止SQL注入的发生。        Dim sqlParameter() As SqlParameter =            {                New SqlParameter("@adminUser", enUser.userID),                New SqlParameter("@adminPwd", enUser.PassWord)             }        Dim com As SqlCommand = New SqlCommand(str, sqlCon)        sqlCon.Open()        com.CommandType = CommandType.StoredProcedure        com.Parameters.AddRange(sqlParameter)        table = com.ExecuteScalar()        Return table    End FunctionEnd Class

在D层使用了一个存储过程,至于什么是存储过程,感兴趣的查一查

如果不使用存储过程的话,那么

 

 CommandType.StoredProcedure

点后边的内容改成text就可以了。

 

本文章仅代表个人见解,如果有问题欢迎大家斧正。