【机房重构个人版】七层登录

一、前言:

       从最初C#版的三层,到VB.NET版的三层,最后再到VB.NET版的七层。可谓是历经了不少的曲折经历。刚开始不知如何下手,各种查资料,各种蒙圈,慢慢的终于有了些眉目。只要坚持,先从简单地代码入手,最终程序的大体轮廓,也就呼之欲出啦。

二、七层结构:

      七层是在三层的基础上演化而来的,也就是在三层的基础上增加了外观层(Facade)、工厂层(Factory)、和接口层(IDAL)。七层的使用使程序之间的耦合性进一步降低,以便于设计出可扩展、易维护的优质程序。


根据上图添加各层之间的引用关系。接下来就是七层登录的相关代码:

UI层:

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">Imports Entity
Imports Facade
Public Class frmLogin

    Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click
        '文本框是否为空
        If txtUserName.Text = "" Then
            MsgBox("请输入用户名!")
            txtUserName.Focus()
            Exit Sub
        End If
        If IsNumeric(txtUserName.Text) = False Then
            MsgBox("用户名请输入数字!")
            txtUserName.Text = ""
            Exit Sub
        End If
        If txtPassword.Text = "" Then
            MsgBox("请输入密码!")
            txtPassword.Focus()
            Exit Sub
        End If
        Try
            '实例化外观层和实体层
            Dim Facade As New Facade.LoginFacade
            Dim UserInfo As New Entity.LoginEntity
            UserInfo.UserName = txtUserName.Text.Trim
            UserInfo.Password = txtPassword.Text.Trim
            Dim strResult As Boolean 'strResult为布尔值,返回类型是布尔类型
            '将U层的信息传入外观层,然后再由外观层进入B层进行判断
            '检验用户名是否正确
            strResult = Facade.CheckUser(UserInfo)
            '实例化DataTable,DataTable是一个虚拟的表
            Dim table As DataTable
            '检验密码是否正确
            table = Facade.CheckPwd(UserInfo)

            Me.Hide()

            frmMain.Show()
        Catch ex As Exception
            MsgBox("用户名或密码错误")
            txtPassword.Text = ""
            txtUserName.Text = ""

        End Try
    End Sub
End Class</span></span></span></span>
Facade层:

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">Public Class LoginFacade
    '检查用户是否存在
    Public Function CheckUser(ByVal UserInfo As Entity.LoginEntity) As Boolean '返回类型也应该是布尔类型
        '实例化B层
        Dim IsUserExists As New BLL.LoginBLL
        Dim flag As Boolean 'flag类型是布尔值
        '用户名是否存在
        flag = IsUserExists.ExistUser(UserInfo)

        If flag = True Then
            Return True
        Else
            Return False
        End If
    End Function
    '检查密码是否正确
    Public Function CheckPwd(ByVal UserInfo As Entity.LoginEntity) As DataTable '返回类型是DataTable
        Dim table As DataTable
        '实例化B层,
        Dim IsPwdExists As New BLL.LoginBLL

        table = IsPwdExists.RightPWD(UserInfo)
        Return table
    End Function
End Class</span></span></span></span>
BLL层

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">Public Class AddUserBLL
    Public Function ExistID(ByVal AddUserInfo As Entity.AddUserEntity) As Boolean
        Dim table As New DataTable
        Dim flag As Boolean
        Dim factory As New Factory.AddUserFactory
        Dim IID As IDAL.AddUserIDAL
        Dim int As Integer
        '运用工厂,创建接口
        IID = factory.CreateIID
        '去实现这个接口
        table = IID.selectID(AddUserInfo)
        If table.Rows.Count = 0 Then
            flag = False
            int = IID.AddUserData(AddUserInfo)
            MsgBox("添加用户成功!", , "提示")

        Else
            flag = True
            MsgBox("用户ID不能重复添加!", , "提示")
        End If
        Return flag
    End Function


End Class
</span></span></span></span>
Factory层:

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">Imports System.Reflection '添加对反射的引用
Imports System.Configuration '添加对配置文件的引用
Imports System.Data
Imports IDAL
'反射+配置文件+抽象工厂
Public Class LoginFactory
    Private Shared ReadOnly AssemblyName As String = "DAL" '程序集名称
    'Dim db As String = System.Configuration.ConfigurationSettings.AppSettings("DB") 
    Public Function CreateIUser() As LoginIDAL  '提供创建对象的接口
        Dim classname As String = "DAL" + "." + "LoginDAL"  '要实例化的D层的类的名称
        Dim IUser As LoginIDAL
        'CType函数将返回表达式显示的转换为指定的数据类型、对象、结构、类或接口后的结果
        IUser = CType(Assembly.Load(AssemblyName).CreateInstance(classname), LoginIDAL) '返回loginIDAL
        Return IUser

    End Function
End Class
</span></span></span></span>
IDAL层:

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">Public Interface LoginIDAL
   '判断用户名是否存在
    Function selectUser(ByVal UserInfo As Entity.LoginEntity) As DataTable
End Interface
</span></span></span></span>
DAL层:

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">Imports System.Data.SqlClient 'system.Data.sqlClient命名空间是SQLServer的.NET Framework数据提供程序
'SQL Server的.NET Framework数据提供程序描述了一个类集合,这个类集合用于访问托管空间中的SQL Server数据库
Imports Entity
Imports IDAL
Imports SQLhelper
Public Class LoginDAL : Implements IDAL.LoginIDAL '实现接口
    Dim sqlHelper As New SQLhelper.sqlhelper
    '判断用户名是否存在

    Public Function selectUser(UserInfo As LoginEntity) As DataTable Implements LoginIDAL.selectUser '实现接口
        Dim sql As String '中间变量,用于储存从数据库中查找的信息
        Dim table As DataTable '声明一个DataTable
        '声明并实例化参数数组
        Dim sqlParams As SqlParameter() = {New SqlParameter("@UserName", UserInfo.UserName),
                                           New SqlParameter("@Password", UserInfo.Password)}
        sql = "select * from User_info where UserID=@UserName and Password=@Password"
        '调用SqlHelper类中的GetDataTable()方法来执行查询,并获取返回值
        table = sqlHelper.ExecSelect(sql, CommandType.Text, sqlParams)
        Return table
    End Function

   
End Class
</span></span></span></span>
SQLHelper层:

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">Imports System.Data
Imports System.Data.SqlClient
'Imports System.Configuration '引入配置文件命名空间必须在管理器中添加引用.
Public Class sqlhelper


    ' Dim strConnction As String = ConfigurationManager.AppSettings("connstring")
    Dim strConnction As String = Configuration.ConfigurationManager.AppSettings("connstring")
    'Dim strConnction As String = "Server=.;Database=chargeRe_sys;User ID=sa;Password=123456"
    Dim conn As New SqlConnection(strConnction)
    Dim cmd As New SqlCommand
    'Exec=execute  '执行
    Public Function ExecSelect(ByVal cmdText As String, ByVal cmdType As CommandType, ByVal paras As SqlParameter()) As DataTable
        Dim sqlAdapter As SqlDataAdapter '定义数据适配器
        Dim table As New DataTable
        Dim dset As New DataSet
        '给cmd赋值

        cmd.CommandText = cmdText 'cmdText为所要执行的sql语句
        cmd.CommandType = cmdType '命令执行的类型
        cmd.Connection = conn
        cmd.Parameters.AddRange(paras) '参数添加
        sqlAdapter = New SqlDataAdapter(cmd) '实例化Adapter
        Try
            conn.Open()
            sqlAdapter.Fill(dset) '用adapter将dataset填充
            table = dset.Tables(0) '
            cmd.Parameters.Clear() '清除参数
        Catch ex As Exception
            MsgBox("数据库操作")
        End Try

        Return table
    End Function</span></span></span></span>
三、配置文件:

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <appSettings>
     <add key="DB" value="sqlserver"/>
      <add key="connstring" value="Server=.;Database=chargeRe_sys;User ID=sa;Password=123456"/>
    </appSettings>

</configuration</span>
></span></span></span>

四、常见问题:

一、未处理NullReferenceException

                                  

更改生成输出路径:DAL——属性——编译——浏览。

                                  

反射的一个原则是:一切皆以UI层的bin文件夹中的dll名称为中心,说白一点,dll就是一个类库。我理解的反射,就是一串拼接的字符串,组成要实例化的类的名字。使用反射加载类时,默认是从UI层中的bin中找的,所以要在UI的bin文件夹下生成D层类的dll,这样才能顺利加载。

二 、未将对象引用设置引用到对象实例

                                                         

①未使用New初始化对象:我们在定义一个实体对象或其他对象时,有时因为疏忽,会少写了New。

②反射+工厂+配置文件有错误:Classname应该是程序名.类名(应符合规范反射规范)






       


评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值