VB.NET版机房收费系统之七层登录

来源:互联网 发布:ad10电路设计软件 编辑:程序博客网 时间:2024/05/16 08:59


七层UML图

   七层登录是在三层登录的基础上加了外观模式抽象工厂模式+反射+配置文件接口SQLHelper。开始之所以学习七层登录,是因为登录模块比较简单,通过简单的例子学习和理解七层架构的优势所在。先易后难,逐步提高。



各层之间的引用关系:




实现步骤:

1、创建Entity,实现业务实体。 
2、创建IDAL,实现接口。 
3、创建DAL,实现接口里的方法。 
4、增加APP.config里的配置信息,为提供DAL的程序集。 
5、创建Factory,返回程序集的指定类的实例。 
6、创建BLL,调用Factory,得到程序集指定类的实例,完成数据操作方法。
7、创建Facade,调用BLL,得到BLL层的处理结果返回值。
8、创建UI,调用Facade里的数据操作方法,实现登录。

 

七层具体展示:

UI层作用:U层负责数据的录入与输出。在U层,先通过调用U层中的验证用户类的验证方法来确认所输入用户是否合法,然后通过调用Façade层验证用户类的查询方法来确认该用户是否存在。)

Public Class FrmLogin    Private Sub btnOK_Click(sender As Object, e As EventArgs) Handles btnOK.Click        '判断输入不能为空          If txtUserName.Text = "" Then            MsgBox("请输入用户名", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)            txtUserName.Focus()        End If        'If IsNumeric(txtUserName.Text) = False Then               If txtPassword.Text = "" Then            MsgBox("请输入密码", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)            txtPassword.Focus()        End If        Entity.LoginEntity.ID = txtUserName.Text.Trim        Dim Facade As New Facade.LoginFacade '定义一个外观对象            Dim UserInfo As New Entity.LoginEntity            UserInfo.UserID = txtUserName.Text.Trim            UserInfo.Password = txtPassword.Text            Dim strResult As Boolean            '将U层的用户信息传入外观层,然后通过外观层传入B层进行判断              strResult = Facade.CheckUser(UserInfo)            If strResult = False Then                MsgBox("用户不存在")                txtUserName.Text = ""                txtUserName.Select()                txtUserName.Focus()            End If            Dim table As DataTable            table = Facade.CheckPwd(UserInfo)            If Trim(txtPassword.Text) = Trim(table.Rows(0).Item(1)) Then                Me.Hide()                FrmMain.Show()            Else                MsgBox("密码不正确")                txtPassword.Text = ""                txtPassword.Select()                txtPassword.Focus()            End IfEnd Sub



Facade层作用:简称F层,该层的作用可以形象的比喻成“纲”,即渔网中能够提携全网的绳子。以登录系统为例,当我们正常登录时,依次应该发生验证用户输入是否合法,查询用户是否存在,(如果存在)添加用户登录记录等功能。简单来讲就是调用Facade层中的这一个函数即实现登录功能。

Public Class LoginFacade    '检查用户是否存在      Public Function CheckUser(ByVal UserInfo As Entity.LoginEntity) As Boolean        Dim IsUserExists As New BLL.LoginBLL        Dim flag As Boolean        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        Dim IsPwdExists As New BLL.LoginBLL        Dim table As DataTable        table = IsPwdExists.RightPWD(UserInfo)        Return table    End FunctionEnd Class


BLL层作用:B层是业务逻辑层,主要是进行逻辑判断并存放各种功能函数。对应于本层中如查询用户是否存在的函数和验证密码的函数均应写在B层中。

Public Class LoginBLL    '检查用户是否存在      Public Function ExistUser(ByVal UserInfo As Entity.LoginEntity) As Boolean        Dim Factory As New Factory.LoginFactory        Dim IUser As IDAL.LoginIDAL        '调用创建用户的工厂方法          IUser = Factory.CreateIUser() '调用工厂的CreatIUser方法创建IUser接口实例          Dim table As New DataTable '中间变量,用于存储D层查询到的数据          Dim flag As Boolean        table = IUser.selectUser(UserInfo)        If table.Rows.Count = 0 Then            flag = False        Else            flag = True        End If        Return flag    End Function    '查看密码是否正确      Public Function RightPWD(ByVal UserInfo As Entity.LoginEntity) As DataTable        Dim Factory As New Factory.LoginFactory        Dim IUser As IDAL.LoginIDAL        Dim table As DataTable '中间变量,用于存储D层查询到的数据          Dim flag As Boolean        IUser = Factory.CreateIUser '调用工厂的方法创建Iuser          table = IUser.selectUser(UserInfo) '调用接口的方法selectUser          'If UserInfo.Password = Trim(table.Rows(0).Item(1)) Then               Return table    End FunctionEnd Class

Factory层作用:工厂层的主要作用是应用配置文件和反射技术实现数据库的更换功能。在Factory层中首先定义程序集的名字和明明空间的名字,将程序集的名字和命名空间的值写在配置文件中,当执行到Factory函数时程序会自动通过读取配置文件中的相应字符,按照路径实例化出相应的对象。

Imports System.Configuration    '添加对配置文件的引用  Imports System.Reflection '添加对反射的引用 Imports IDAL'反射+配置文件+抽象工厂实现数据访问  Public Class LoginFactory    Private Shared ReadOnly AssemblyName As String = "DAL" '数据程序集名称&命名空间DAL      Dim strDB As String = System.Configuration.ConfigurationManager.AppSettings("DB") '于配置文件相连    Public Function CreateIUser() As LoginIDAL        'Dim classname As String = "DAL." + "LoginDAL" '要实例化的D层的类的名称          Dim IUser As LoginIDAL        'CType函数将返回表达式显示地转换为指定的数据类型、对象、结构、类或接口后的结果          Dim className As String = AssemblyName + "." + "LoginDAL" '如果要更改数据库,D层相应的类要提前写好        IUser = CType(Assembly.Load(AssemblyName).CreateInstance(className), IDAL.LoginIDAL)        Return IUser    End FunctionEnd Class


IDAL层作用:IDAL层中主要放置接口函数

Public Interface LoginIDAL    '判断用户名是否存在      Function selectUser(ByVal UserInfo As Entity.LoginEntity) As DataTableEnd Interface


DAL层(作用:实现接口中的方法并调用SqlHelper中的方法)

Imports System.Data.SqlClient  'system.Data.SqlClient 命名空间是SQLSever的.NET Framework数据提供程序  'SQL Sever 的.NET Framework数据提供程序描述了一个类集合,这个类集合用于访问托管空间中的SQL Sever数据库 Public Class LoginDAL : Implements LoginIDAL    '实现接口中的方法      Private sqlHelper As New SQLHelper.sqlHelper    '判断用户名是否存在      Public Function selectUser(UserInfo As Entity.LoginEntity) As DataTable Implements LoginIDAL.selectUser        Dim sql As String  '中间变量,用于储存从数据库中查找到的信息          Dim table As DataTable  '声明一个DataTable          '声明并实例化参数数组          Dim sqlParams As SqlParameter() = {New SqlParameter("@UserID", UserInfo.UserID),                                               New SqlParameter("@Password", UserInfo.Password)}        sql = "select * from User_Info where UserID=@userID and PWD=@Password"        '调用SqlHelper类中的GetDataTable()方法来执行查询,并获取返回值          table = sqlHelper.ExecSelect(sql, CommandType.Text, sqlParams)        Return table    End FunctionEnd Class


SqlHelper层(作用:执行增删改查等功能,sqlhelper中的主要函数包括获得执行带参数和不带参数的非查询功能,执行带参数的和不带参数的获取datatable的查询功能,获取带参数的和不带参数的获得一个阅读器的查询功能)

Imports System.Data.SqlClient Imports System.Configuration '添加对配置文件的引用Imports System.Reflection '添加对反射的引用Public Class sqlHelper    '数据库连接    Dim strConnection As String = ConfigurationManager.AppSettings("DB")    Dim conn As New SqlConnection(strConnection)    Dim cmd As New SqlCommand    Public Function ExecSelect(ByVal cmdText As String, ByVal cmdType As CommandType, ByVal paras As SqlParameter()) As DataTable        Dim sqlAdapter As SqlDataAdapter   '定义数据适配器        Dim dt As New DataTable        Dim ds As New DataSet        '给cmd 赋值        cmd.CommandText = cmdText        cmd.CommandType = cmdType        cmd.Connection = conn        cmd.Parameters.AddRange(paras) '添加参数        sqlAdapter = New SqlDataAdapter(cmd) '实例化Adapter        Try            sqlAdapter.Fill(ds) '用adapter将dataset填充            dt = ds.Tables(0) 'datatable是dataset的第一个表            cmd.Parameters.Clear()  '清除参数        Catch ex As Exception            MsgBox("数据库操作")        Finally            Call CloseCmd(cmd) '关闭cmd命令        End Try        Return dt    End Function    Public Sub CloseCmd(ByVal cmd As SqlCommand)        If Not IsNothing(cmd) Then '如果cmd存在            cmd.Dispose() '销毁            cmd = Nothing        End If    End SubEnd Class




Entity实体(作用:设置各个参数的属性,在各层之间传递)

Public Class LoginEntity      Public Shared ID As String '用于记录登录时的用户名      Private _UserID As String    Public Property UserID As String        Get            Return _UserID        End Get        Set(value As String)            _UserID = value        End Set    End Property    Private _password As String    Public Property Password As String        Get            Return _password        End Get        Set(value As String)            _password = value        End Set    End PropertyEnd Class


遇到的问题:

在调试的过程中遇到下面这个问题。



解决方法:右击D层-属性-生成-输出路径-点击浏览改到U层的Bin里边即可

 

通过这个错误学到一个很重要的知识:

   .net类加载的机制就是默认从本程序集的bin文件中找,所以bin文件夹中一定要有要加载的程序集的dll)。UI层中bin文件夹中dll叫什么名字AssemblyPath就使用什么名字,bin内部类的全名叫什么,className就写成什么全名。.net中的引用:加入对某个程序集的引用就能在程序集有变化时自动拷贝dll。

小结:

   七层登录实现了,可是这只是开始的第一步,下面的重构才是真正学东西的环节。我要加油!

    关于反射+配置文件,在下一篇博客介绍。










原创粉丝点击