`
jishublog
  • 浏览: 870489 次
文章分类
社区版块
存档分类
最新评论

收费系统三层+抽象工厂+反射实例

 
阅读更多

在软件体系架构中分层结构是最常见的,也是最重要的一种结构。微软推荐的分层式结构一般分为三层,自上至下分别是:表示层、业务逻辑层、数据持久层,这里所说的三层是按照功能将系统在开发过程中进行划分,但是这里少了很重要的一层就是实体层,在三层架构中实体层没有显著的功能,它主要的功能是负责各层间参数的传递。在业务层和数据访问层中定义的每个函数所用的参数来自实体层,函数间参数的传递也是使用的实体层。


三层结构+抽象工厂+反射的包图:

上面的包图中IDAL接口封装了DAL中对数据库操作的方法,DAL继承了IDAL中的接口类实现了具体的操作,Factory工厂包使用反射获得了DAL中具体数据库表的实例。当BLL层需要使用数据库中数据时,只需调用Factory包中的方法返回所需要的数据库表。这样的实现了面向接口编程,降低了程序和数据库的耦合程度。在更换数据库时只需扩展DAL包中的类图,继承IDAL保重的类,遵守了扩展开放修改封闭的原则。


.NET程序编译机制


解决方案和程序集是.NET程序的两个重要结构,当创建一个新项目时.NET会让我们同时创建解决方案和程序集,一个解决方案内能够同时包含多个程序集。


1、解决方案

解决方案封存了程序集和程序集运行需要的环境,在创建解决方案时.NET会在指定目录下创建一个以解决方案命名的项目文件,项目文件内封存了项目所需的程序集。

在生成解决方案时,每个程序集会在自己的运行环境下生成所需的程序组件,如果是类或接口之类的文件,程序集编译后会生成DLL文件,生成的DLL文件可以被其他程序调用。


2、程序集

程序集封装了程序运行所需的组件,一个程序集中包括程序运行的组成文件,如:接口、类、Html文件等。在生成解决方案(编译生成项目)后程序集一般会生成DLL文件、exe文件或COM组件等程序文件,而解决方案封存了这些程序文件,一般情况下启动项目会生成EXE文件,其它引用项目会生成DLL文件。

需要重点强调的是程序集的引用关系,.NET项目的引用关系调用的并不是地址而是把被引用的文件封存在程序集Bin文件中,也就是说在程序集Bin文件中会生成被引用文件的源文件,这样程序集在运行时会在自己的bin文件中查找被引用的文件,而不用去其它地方查找,使得.NET能够更高效的运行。


了解了.NET程序编译机制我们就可以很简单的使用反射功能来实现程序的解耦,在上面的包图中Factory包没有引用DAL包但使用反射可以实例化DAL包,在生成解决方案后要把生成的DALDLL文件手动放到启动项目(UI包)或Factory包的Bin文件中,否则会在使用反射时弹出错误,提示“未能加载文件或程序集“DAL”或它的某一个依赖项。系统找不到指定的文件。


二、登陆具体实现


UI

负责启动系统,显示数据,实现UI逻辑。系统的配置文件写入该层,例如:为反射提供字符串或者为连接数据库提供字符串的App.config必须放在该层,因为系统在调用时会在启动程序集下面查找这些文件,这牵扯到了.NET程序的运行机制问题具体以后再总结,如果没有找到将会导致程序出错。


'======================================================================================
'作   者: Zhang
'编写时间:2013-05-25
'功   能:UI层,实现系统登陆
'======================================================================================

    Private Sub btnLoginSystem_Click(sender As Object, e As EventArgs) Handles btnLoginSystem.Click

        '判断是否已经输入用户名和密码
        If txtUsername.Text.Trim = "" Then

            '提示输入用户名
            MsgBox("请输入用户名!", vbOKOnly, "提示")
            Exit Sub

        Else

            If txtPassword.Text = "" Then

                '提示输入密码
                MsgBox("请输入密码!")
                Exit Sub

            End If

        End If

        Dim strUsername As String = txtUsername.Text.Trim   '定义保存用户名的字符串
        Dim strPassword As String = txtPassword.Text        '定义保存密码的字符串
        Dim EnAdmin As New Entity.AdminInfoEntity           '定义实体传参的对象
        Dim LoginMan As New BLL.AdminBLL                    '定义业务逻辑层

        '向实体层传递使用的参数
        EnAdmin.ad_Username = strUsername
        EnAdmin.ad_Password = strPassword

        Try
            '实现登陆过程
            Dim Admin1 As Entity.AdminInfoEntity = LoginMan.Login(EnAdmin)

            '登陆成功后显示主窗体,按照用户级别分别显示不同的功能菜单
            If Admin1.ad_Level = "Operator" Then

                '如果是普通的操作员,高级功能将不能使用
                frmMain1.tspMenu2.Visible = False
                frmMain1.tspMenu3.Visible = False

            Else

                If Admin1.ad_Level = "Admin" Then

                    frmMain1.tspMenu3.Visible = False

                End If

            End If

            frmMain1.Show()             '显示主窗体
            mo_Username = strUsername   '保存登陆的用户名

            Me.Close()                  '关闭登陆窗体

        Catch ex As Exception

            MsgBox(ex.Message, vbOKOnly, "提示信息")    '错误提示框

        End Try

    End Sub

BLL

UI层调用,不知道UI层的存在。负责业务逻辑,在调用具体的数据库表中的数据时,应定义接口类,并使用工厂类中的DataAccess类方法反射实例化相应的DAL类。在使用时必须引用Entity实体程序集、Factory工厂程序集、IDAL数据库接口程序集。


Public Class AdminBLL
    Dim Mflag As Boolean = False
    Dim DataAccess As New Factory.DataAccess        '定义数据库访问工厂类

    '======================================================================================
    '编写时间:2013-05-25
    '函数类别:BLL层,登陆判断函数
    '函数功能:主要对传递来的Admin信息进行判断,并抛出相应的错误异常
    '======================================================================================
    Public Function Login(ByRef Admin As Entity.AdminInfoEntity) As Entity.AdminInfoEntity

        Dim SelectAdmin As IDAL.IAdminIDAL = DataAccess.CreateAdmin     '定义管理员表类,用于检索管理员
        Dim DALOnwork As IDAL.IOnWorkDAL = DataAccess.CreateOnwork      '定义正在工作管理员表类
        Dim Admin1 As Entity.AdminInfoEntity = Nothing                  '定义传参实体
        Dim Onwork As New Entity.OnWorkEntity                           '定义正在工作管理员表实体

        Onwork.on_Username = Admin.ad_Username  '为Onwork的用户名传参设置值
        
        Admin1 = SelectAdmin.SelectAdminUser(Admin) '按照用户名在数据库中查找相应记录

        '判断用户信息是否存在
        If Not Admin1 Is Nothing Then

            '判断密码是否输入正确
            Admin1 = Nothing
            Admin1 = SelectAdmin.SelectAdmin(Admin)
            If Not Admin1 Is Nothing Then

                Mflag = True

            Else

                Throw New Exception("密码错误,请重新输入密码!")    '抛出异常

            End If
        Else

            Throw New Exception("用户不存在,请重新输入!") '抛出异常

        End If

        '实现登录管理
        LoginManager(Onwork)

        Return Admin1

    End Function

    '======================================================================================
    '编写时间:2013-05-25
    '函数类别:BLL层,登陆管理函数,
    '函数功能:主要实现登录时对数据库表的操作
    '======================================================================================
    Public Function LoginManager(Onwork As Entity.OnWorkEntity) As Entity.OnWorkEntity

        Dim DALOnwork As IDAL.IOnWorkDAL = DataAccess.CreateOnwork          '创建并实例化DALOnwork表
        Dim DALWorklog As IDAL.IWorkLogIDAL = DataAccess.CreateWorkLog      '创建并实例化DALWorklog表
        Dim Mflag As Boolean = False                                        '定义中间参数
        Dim Onwork1 As Entity.OnWorkEntity = DALOnwork.SelectLog(Onwork)    '定义正在上机的实体类,并检索该用户是否正在操作系统

        '在登陆前查询该用户上次是否正常上机
        If Onwork1 Is Nothing Then

            '没有在上机的话,在Onwork表中插入该管理员上机记录
            DALOnwork.InsertLog(Onwork)

        Else

            '插入教师值班记录
            Mflag = DALWorklog.InsertLog(Onwork)

            If Mflag = True Then

                DALOnwork.DeleteLog(Onwork)     '删除正在上机的教师记录
                DALOnwork.InsertLog(Onwork)     '增加教师新的上机记录

            End If

        End If

        Return Onwork1
    End Function
End Class

IDAL

BLL层和DAL层调用,提供了DAL层的所需要的接口。该接口降低了项目中各层之间的耦合程度,能够简单的实现更换数据库。

'======================================================================================
'作   者: Zhang
'编写时间:2013-05-25
'类 名 称:类名为IAdminIDAL
'功   能: 管理员类的接口,主要实现对系统的操作
'======================================================================================
Public Interface IAdminIDAL

    '查询系统用户名
    Function SelectAdminUser(ByRef Admin As Entity.AdminInfoEntity) As Entity.AdminInfoEntity

    '查询系统用户名和密码
    Function SelectAdmin(ByRef Admin As Entity.AdminInfoEntity) As Entity.AdminInfoEntity

    '修改用户密码信息
    Function UpdateAdmin(ByRef Admin As Entity.AdminInfoEntity) As Boolean

    '按照用户级别查询系统用户
    Function SelectUserByLevel(ByRef Admin As Entity.AdminInfoEntity) As DataSet

    '删除用户
    Function DelectUser(ByRef Admin As Entity.AdminInfoEntity) As Boolean

    '新增用户
    Function InsertUser(ByRef Admin As Entity.AdminInfoEntity) As Boolean

    '获取系统用户
    Function SelectAdminName() As String()

    '按用户名查询到用户真实姓名
    Function SelectTrueName(ByRef Admin As Entity.AdminInfoEntity) As String

End Interface

Factory

工厂程序集,被BLL层调用,并调用IDAL层,引用反射,使用反射得到具体DAL层类的实例。使用配置文件获取具体的数据库字符串,决定是实例化哪种类型的数据库。

Imports System.Reflection       '引用反射
Imports System.Configuration    '引用配置文件
Imports IDAL                    '引用接口程序集

'======================================================================================
'作   者: 张信秀
'编写时间:2013-06-06
'类名称、功能:类名为DataAccess,是封装数据访问的工厂类
'======================================================================================
Public Class DataAccess

    Private ReadOnly AssemblyName As String = "DAL"             '定义程序集名称
    Dim db As String = ConfigurationSettings.AppSettings("DB")  '获取配置文件中的字符串

    '创建Admin表
    Public Function CreateAdmin() As IAdminIDAL

        Dim className As String '定义实例化类的名称
        Dim Admin As IAdminIDAL '定义类的返回类型

        className = AssemblyName + "." + db + "AdminDAL"    '为实例化类名称赋值,程序集名称+类名
        Admin = CType(Assembly.Load(AssemblyName).CreateInstance(className), IDAL.IAdminIDAL)   '反射实例化  

        Return Admin    '返回值

    End Function

    '创建Onwork表
    Public Function CreateOnwork() As IOnWorkDAL

        Dim className As String         '定义实例化类的名称
        Dim OnworkData As IOnWorkDAL    '定义返回值

        className = AssemblyName + "." + db + "OnWorkDAL"       '为实例化类名称赋值,程序集名称+类名
        OnworkData = CType(Assembly.Load(AssemblyName).CreateInstance(className), IOnWorkDAL)   '反射,实例化具体需要的类

    '创建WorkLog表
    Public Function CreateWorkLog() As IWorkLogIDAL

        Dim className As String                 '定义实例化类的名称
        Dim WorkLogData As IDAL.IWorkLogIDAL    '定义返回值

        className = AssemblyName + "." + db + "WorkLogDAL"      '为实例化类名称赋值,程序集名称+类名
        WorkLogData = CType(Assembly.Load(AssemblyName).CreateInstance(className), IWorkLogIDAL)    '反射,实例化具体需要的类

        Return WorkLogData  '返回值
    End Function

End Class

DAL

继承了IDAL层的类,实现了IDAL接口类中的功能,对数据库表进行操作。可以进行扩展,但不支持更改。在编写时可以使用SqlHelper来实现具体的数据库访问,减轻复杂的对象使用。

Imports Microsoft.ApplicationBlocks.Data    '引用SqlHelper块
Imports System.Data.SqlClient               '引用Sql对象块
Imports IDAL                                '引用接口程序集

'-------------------------------------------------------------------------
'类属性:管理员信息类,主要保存管理员信息
'类操作:主要实现管理注册信息的操作,对管理员信息进行增加、删除、修改等
'-------------------------------------------------------------------------
Public Class SqlAdminDAL
    Implements IAdminIDAL

    Dim strCon As New ConnStringDAL '定义数据库连接字符串类,并实例化

    '定义查询用户名函数,根据用户名查询用户
    Public Function SelectAdminUser(ByRef Admin As Entity.AdminInfoEntity) As Entity.AdminInfoEntity Implements IAdminIDAL.SelectAdminUser

        Dim strQry As String = "select * from tblAdmin where ad_Username=@username" '定义查询字符串

        '使用Using语句,便于销毁对象
        Using sqlCon As New SqlConnection(strCon.ConnectString)

            Dim sqlCom As New SqlCommand(strQry, sqlCon)    '定义Command对象
            Dim Admin1 As Entity.AdminInfoEntity = Nothing  '定义返回实体类

            sqlCom.Parameters.Add(New SqlParameter("@username", Admin.ad_Username)) '为Command对象增加参数值

            sqlCon.Open()

            Dim sqlReader As SqlDataReader = sqlCom.ExecuteReader()     '定义DataReader对象,读取查询结果集

            '按顺序读取数据
            While (sqlReader.Read())

                '实例化具体的实体类
                If Admin1 Is Nothing Then
                    Admin1 = New Entity.AdminInfoEntity
                End If

                Admin1.ad_Username = sqlReader.GetString(1) '为实体类用户名赋值
                Admin1.ad_Password = sqlReader.GetString(2) '为实体类密码赋值

            End While

            Return Admin1   '返回实体类

        End Using
    End Function
End Class

总结:抽象工厂让具体的创建实例过程与BLL层分离,BLL层是通过IDAL接口层操纵实例,通过反射防止了BLL层对数据库的依赖。



分享到:
评论

相关推荐

    asp.net 抽象工厂分层框架

    asp.net 抽象工厂模式经典分层框架,反射实例化类,附带数据库

    三层结构入门源码(C#)

    Asp.net三层登录示例源码 连接数据库配置一下web.config的SQLServer WebDAL节点是需要生成的抽象工厂实例 本例子是3层结构+反射抽象工厂 本人也是初学者所以代码写的菜请大家指点。

    JAVA 范例大全 光盘 资源

    实例34 花园布局(抽象工厂模式) 80 实例35 几何图形(适配器模式) 82 第6章 字符串 85 实例36 获取字符串长度 85 实例37 比较字符串 86 实例38 Java字符串与文件的互转 88 实例39 截取带汉字的字符串 91 ...

    三层结构入门源码asp.net2.0

    默认帐号密码admin连接数据库配置一下web.config的SQLServerWebDAL节点是需要生成的抽象工厂实例本例子是3层结构+反射抽象工厂本人也是初学者所以代码写的菜请大家指点。SQLAccess由于时间问题,所以没有写。

    解剖PetShop.rar

    5、DALFactory=数据层的抽象工厂(创建反射) 6、SQLServerDAL=SQLServer数据访问层 / OracleDAL=Oracle数据访问层 DBUtility 数据库访问组件基础类 二、项目引用关系 1、Web 引用 BLL。 2、BLL 引用 IDAL,Model...

    七彩云在线超市管理系统

    抽象工厂,用于创建各种数据对象的方法,这里有配置文件和反射的运用。 ************************************************************************* -------IDAL--------数据接口层(控制是选择什么类型的数据库...

    asp.net知识库

    泛型技巧系列:用泛型打造可复用的抽象工厂 体验.net2.0的优雅(四):Provider、策略、控制反转和依赖注入 泛型最佳实践 asp.net 2.0下嵌套masterpage页的可视化编辑 C# 2.0与泛型 动态调用对象的属性和方法——...

    亮剑.NET深入体验与实战精要2

    14.4.4 实现抽象工厂模式 519 14.4.5 工厂模式的三层架构图 521 本章常见技术面试题 522 职场智慧之程序员的职业规划 523 本章小结 524 第15章 大型网站的性能优化与安全 525 15.1 高效C#编码优化 526 15.2 页面...

    亮剑.NET深入体验与实战精要3

    14.4.4 实现抽象工厂模式 519 14.4.5 工厂模式的三层架构图 521 本章常见技术面试题 522 职场智慧之程序员的职业规划 523 本章小结 524 第15章 大型网站的性能优化与安全 525 15.1 高效C#编码优化 526 15.2 页面...

    javaSE代码实例

    第10章 构造器——对象制造的工厂 176 10.1 基础知识 176 10.1.1 编写构造器的语法规则 176 10.1.2 访问限制修饰符与构造器 176 10.1.3 构造器与返回类型 179 10.2 创建对象 180 10.3 重载构造器 181 ...

    Spring面试题

    没有使用一堆抽象工厂、服务定位器、单元素(singleton)和直接构造(straight construction),每一个对象都是用其协作对象构造的。因此是由容器管理协作对象(collaborator)。 Spring即使一个AOP框架,也是一IOC...

Global site tag (gtag.js) - Google Analytics