登陆窗体 抽象工厂+反射

本文介绍了在.NET环境下,基于三层架构的登录窗体设计,通过抽象工厂和反射来实现数据库的灵活切换。文章详细阐述了三层架构的各层职责,并解释了如何使用实体对象传递数据,以及接口在减少代码重复性中的作用。在实施过程中遇到的配置文件错误及解决方案也在文中提及。
摘要由CSDN通过智能技术生成

三层视频看完之后,就照着例子悄悄的敲,敲的不专心,又返回来看视频,继续敲。其实,第一次敲的比较盲目,没太理解一些语句,和逻辑。然后师傅就过来给我串了串,然后,就感觉豁然开朗了,视频中的小例子,在U,B,D层是通过传参数UserName,和Password两个参数进行的。师傅有要求传个实体,最好能加上抽象工厂+反射,为了变更数据库时使用。接下来就说一下就说一下,具体实现过程:

一.先说一下,从视频中学到的三层概念:

U层作用(3个):

1.展示给用户界面

2.识别用户操作

3.采集用户输入信息

不包含任何业务逻辑

B层作用:

先获取U层的数据和指令,然后执行业务逻辑,或通过DAL写入数据源

最后,还要将D层必要数据传给U层。

D层作用:

提供基本的数据访问,不包含任何业务逻辑。

先看一下我的包图:


在这里解说一下:

外观模式;一般放在设计初期,加在U层和B层,B层和D 层之间,这样可以提供一个简单接口,使层与层之间耦合度降低。在这里就是,利用这个接口降低,U层与B层之间的耦合。

实体层:视频版的登陆窗体数据简单,传的是参数。如果有很多数据,都较麻烦了,不如传个实体,将参数都放在实体里面。

抽象工厂+反射:作用就是为了更换数据库。只需在配置文件中更改数据库就能进行自动更改,而无需在层中大量手动修改代码。从抽象工厂中出来的就是,一个具体的D层的类了。

接口:开始对这个IDAL没能很好的理解,其实,就是在更换数据库时,减少写入D层不同类中的代码重覆。

这是我的解决方案:


U层:得到,用户输入的username ,和password并以实体形式传给外观层的方法(传给外观层)。

 Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click
        Dim username = txtUserName.Text.Trim()
        Dim password = txtPassword.Text

        Dim user1 As New Model.UserInfo
        user1.UserName = username
        user1.Password = password

        Dim userFac As New Facade.LoginFAC
        Dim str As String

        str = userFac.strRusult(user1)'等号右边是将user1传给外观层(正向),等号左边现在是空的。
        Select Case str               '将传回来的字符串给str后,进行Select语句。
            Case "用户不存在"
                MessageBox.Show("用户不存在,请重新输入!")
                txtUserName.Text = ""
                txtPassword.Text = ""
                txtUserName.Focus()
            Case "密码不正确"
                MessageBox.Show("密码不正确,请重新输入!")
                txtPassword.Text = ""
                txtPassword.Focus()
            Case "登陆成功!"
                MessageBox.Show("恭喜你,登陆成功!")
            Case "登陆次数达到三次"
                MessageBox.Show("登陆次数达到三次, 退出重新进入!")
                Me.Close()
        End Select


    End Sub

Facade层:U层里面Select有四个分支(即四种情况),而我的系统暂时只想考虑前三种情况,所以在外观层里面就根据需要,放了三种。
使U层简化,降低了耦合。

Imports BLL
Public Class LoginFAC
    Public Function strRusult(user As Model.UserInfo) As String
        Dim checkUser As New BLL.CheckUser

        If Not checkUser.IsExist(user) Then'调用B层方法,将user传给B层
            Return "用户不存在"
        ElseIf Not checkUser.CheckPassword(user) Then
            Return "密码不正确"
        Else
            Return "登陆成功!"

        End If



    End Function
End Class

B层:进行逻辑处理,进行用户名和密码的逻辑处理。

Imports Factory
Imports IDAL
Public Class CheckUser
    Public Function IsExist(ByVal user As Model.UserInfo) As Boolean
        Dim Iuser As IDAL.IUserInfo
        Dim FacUser As New Factory.FactoryDB

        Iuser = FacUser.CreatIUser()
        If Iuser.QueryUserInfo(user).UserName = "" Then
            Return False
        Else
            Return True
        End If
    End Function
    Function CheckPassword(ByVal user As Model.UserInfo) As Boolean
        Dim Iuser As IDAL.IUserInfo
        Dim FacUser As New Factory.FactoryDB

        Iuser = FacUser.CreatIUser()
        If Iuser.QueryUserInfo(user).Password = "" Then
            Return False
        Else
            Return True
        End If
    End Function
End Class

D层:进行数据库连接。在这里利用配置文件自动连接数据库。

     D层的每个类都实现了,接口中的方法。

Imports Model
Imports IDAL
Imports System.Data.SqlClient
Public Class SqlUserDAO : Implements IUserInfo
    '调用配置文件与数据库连接
    Dim strconn As String = System.Configuration.ConfigurationSettings.AppSettings("conStr")
    Dim conn As SqlConnection = New SqlConnection(strconn)
    Public Function QueryUserInfo(ByVal user As UserInfo) As UserInfo Implements IUserInfo.QueryUserInfo
        Dim cmd As New SqlCommand
        cmd = conn.CreateCommand()

        cmd.CommandText = "select * from Users where UserName=@username and Password=@password"
        cmd.CommandType = CommandType.Text
        cmd.Parameters.Add(New SqlParameter("@username", user.UserName))
        cmd.Parameters.Add(New SqlParameter("@password", user.Password))

        conn.Open()
        Dim reader As SqlDataReader
        reader = cmd.ExecuteReader
        Dim user3 As New Model.UserInfo
        'user3 = Nothing

        While (reader.Read())

            user3.UserName = reader.GetString(1)
            user3.Password = reader.GetString(2)
        End While
        conn.Close()
        Return user3


    End Function
End Class

接口层:

Public Interface IUserInfo
    Function QueryUserInfo(ByVal user As Model.UserInfo) As Model.UserInfo
End Interface

抽象工厂层:利用配置文件选取数据库,并创建一个接口类型。

Public Class FactoryDB
    Private Shared ReadOnly AssemblyName As String = "DAL" '数据程序集名称
    Dim strDB As String = System.Configuration.ConfigurationSettings.AppSettings("DB")

    Public Function CreatIUser() As IDAL.IUserInfo
        Dim classname As String = "DAL" + "." + strDB + "UserDAO"

        Return CType(Assembly.Load(AssemblyName).CreateInstance(classname), IDAL.IUserInfo)
    End Function


End Class

配置文件:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
  <appSettings>
      <add key ="DB" value ="Sql"/>'更改字符串“Sql”为“Access”则可进行数据库的更换!
    <add key ="conStr" value ="Server=tiger-PC;Database=Login;User ID=sa;Password=123456"/>'连接数据库字符串。
    </appSettings>
  
  </configuration>


总结:逻辑上貌似正确的,实现的过程中也遇到了一些问题,比如配置文件的时候,出现“未将对象引用配置到对象的实例”。具体问题原因和解决方法见我师父的博客:http://blog.csdn.net/u010924834/article/details/37995321。

     三层,是机房重构的必经之路,深刻理解三层理念,才能做好机房重构。



评论 38
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值