【机房重构】——七层登陆

            机房重构三层转七层说难也不难,说简单也不简单,登陆进行了半个月才完成从三层到七层的转换,再加上对思路上的理解,现在我的问题是基本上了解了七层的数据传递,方法调用等,欠缺的地方是:我最欠缺的不是说对七层的理解,也不是说七层如何写,而是从三层到七层的这个转换的过程。

 【一】三问题:

    1、为什么要用抽象工厂?如何抽象出来的抽象工厂,抽象工厂抽象的是什么?

    抽象工厂模式的出现就是与具体数据库访问解除了依赖,以备我们的软件在不同数据库上运行,可以使我们灵活地更换到其他数据库上,就是说对具体的数据库(SQL,Access等)进行了抽象,俗称抽象工厂。

      想知道为什么引入抽象工厂,就得从接口入手,为什么要使用接口呢?

      为什么要使用接口呢,原因有两个,第一是用户提出新需求,自己再不改变源码的情况下更换数据库;第二是从开发公司考虑,为了适应不同的数据库,每次需要修改BLL层源代码,再编译程序,发布程序比较麻烦,那么具体实现步骤是创建新的工厂项目类,然后再类中实现返回产品接口的方法,通过Config读取配置数据,针对不同数据库,返回不同实现接口的对象,最后修改BLL层的调用方式为简单工厂调用,用接口隐式声明,但通过工厂创建,这样我们就可以通过修改配置文件实现不同数据库的访问,实现了简单工厂的设计模式。

      有了简单工厂,为什么还要使用抽象工厂呢?

      原因是一个大项目中包含很多的模块,不同的模块就要创建不同的接口,那么如何返回很多实现接口的对象呢?在简单工厂模式中只能编写多块相似的代码,通过判断数据库的类型返回具体的对象,这样就造成大量的代码冗余,这里采用优化的方法,即抽象公共的部分,通过抽象类调用具体实现类,可以产生一批有关联的产品,例如通过配置文件读取是SQL数据库类型,那么得到SQL的工厂,工厂里的产品都是通过访问SQL数据库数据产生的产品。可以说对于简单工厂模式一次只能创建一个对象,而对于抽象工厂模式实现一次创建一些类相互依赖对象的需求.

    2、配置文件是什么?为什么要有配置文件?

    是什么?配置文件是标准的 XML 文件,XML 标记和属性区分大小写。随安装程序一起被安装到计算机上的文件,里面存放着安装好的应用程序运行时所需要的参数,能干什么?它可以按需要更改参数,开发人员可以使用配置文件来更改设置,而不必重编译应用程序。配置文件的好处?还是要在系统的不断实现中继续去感受,目前能够体会到的就是在数据库连接字符上和数据库的更换上,实际上用了配置文件,已经单单在这两方面给我们省去很大的工作量。

    3、为什么要用抽象工厂与反射的结合?什么是反射?两者如何结合?

    为什么要把抽象工厂与反射结合?这个问题我给出的答案是反射是抽象工厂与配置文件和数据库间的桥梁。什么是反射?反射其实就是通过反编译解析出类或DLL文件的结构,然后通过遍历得到相应的元素,它就是通过动态解析,得到我们所需的属性和方法,通过反射机制我们可以动态的通过改变配置文件的方式来加载、调用一些类或者方法等。

 【二】难点之后,登陆时序图和代码块:

    1、七层登陆时序图

    1、七层登陆代码块 

        1)、Entity

'/**************************
'类名称: Users
'命名空间: Entity
'创建时间: 2017/3/9 17:00:24
'作者: 连迎迎
'小组: 
'修改时间: 
'修改人: 
'版本号: 
'/***************************

Public Class User

#Region "定义字段"
    Private _userid As String
    Private _password As String
#End Region

    '定义属性过程

    Public Property UserId() As String
        Get
            Return _userid
        End Get
        Set(value As String)
            _userid = value
        End Set
    End Property
    Public Property Password As String
        Get
            Return _password
        End Get
        Set(value As String)
            _password = value
        End Set
    End Property
 
End Class
        2)、DAL

'/**************************
'类名称: LoginDAL
'命名空间: DAL
'创建时间: 2017/3/9 16:58:53
'作者: 连迎迎
'小组: 
'修改时间: 
'修改人: 
'版本号: 
'/***************************
Imports System.Data.SqlClient '添加数据库
Imports System.Configuration '引用配置文件
Imports IDAL
Imports Entity
Imports System.DateTime

Public Class LoginDAL : Implements IDAL.LoginIDAL
    '在数据库表User中查找有登陆界面的用户

    Public Function SelectUser(UserInfo As User, ByRef table As DataTable) As DataTable Implements LoginIDAL.SelectUser
        '实例化SQLHelper对象
        Dim sqlHelperObject As New SQLHelper

        Dim sql As String
        '定义变量,接受数据库返回的数据

        '实例化参数数组,赋值
        Dim sqlParams As SqlParameter() = {New SqlParameter("@userid", UserInfo.UserId), New SqlParameter("@password", UserInfo.Password)}
        'sql语句执行查询
        'sql = "proc_login"
        sql = "select * from User_Info where userId=@UserID and Password=@Password"
        '调用SQLHelper类中的ExecSQLSelect方法执行select语句查询
        table = sqlHelperObject.ExecSqlSelect(sql, CommandType.Text, sqlParams)
        Return table
    End Function
End Class

   3)、IDAL    
Imports System.Configuration
Imports Entity
Public Interface LoginIDAL
    Function SelectUser(ByVal userInfo As Entity.User, ByRef table As DataTable) As DataTable
End Interface

   4)、App.Config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <add name="UI.My.MySettings.charge_sysConnectionString" connectionString="Data Source=.;Initial Catalog=charge_sys;Persist Security Info=True;User ID=sa" providerName="System.Data.SqlClient"/>
  </connectionStrings>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
  <appSettings>
    <add key="SqlConnStr" value="server=.;database=charge_sys;User ID=sa;Password=1"/>
    <add key="DB" value="DAL"/>
  </appSettings>
</configuration>

   5)、Factory

'/**************************
'类名称: LoginFactory
'命名空间: Factory
'创建时间: 2017/3/9 17:02:15
'作者: 连迎迎
'小组: 
'修改时间: 
'修改人: 
'版本号: 
'/***************************
Imports System.Reflection '引用反射,反射的作用就是方便不同数据库的连接
Imports System.Configuration '添加配置文件
Imports IDAL
Imports Entity
Public Class LoginFactory
    Private Shared ReadOnly AssemblyName As String = "DAL" '定义一个变量赋予其数据程序及名称&命名空间DAL
    '读配置文件
    Dim db As String = System.Configuration.ConfigurationSettings.AppSettings("DB") '使用配置文件
    Public Function CreateUser() As IDAL.LoginIDAL
        Dim className As String = db + "." + "LoginDAL" '实例化D层的名称
        
        Return CType(Assembly.Load(AssemblyName).CreateInstance(className), IDAL.LoginIDAL)
        'CType函数将返回表达式显示转换为指定数据类型、对象、结构、类或接口后的结果
        'Load中是程序集的名称,也就是生成的DLL的完整名称,带命名空间
        'GetType的参数是类的完整名称,带命名空间 
    End Function
End Class


     6)、BLL

'/**************************
'类名称: LoginUser
'命名空间: BLL
'创建时间: 2017/3/9 16:57:56
'作者: 连迎迎
'小组: 
'修改时间: 
'修改人: 
'版本号: 
'/***************************
Imports System.Data.SqlClient
Imports IDAL
Imports Entity
Imports Factory
Imports System.DateTime

Public Class LoginUser
    '判断用户是否存在
    Public Function isUserExist(ByVal UserInfo As Entity.User) As ArrayList
        '定义接口
        Dim iDalObject As IDAL.LoginIDAL
        Dim table As New DataTable
        Dim mylist As New ArrayList
        '实例化工厂
        Dim factoryObject As New Factory.LoginFactory
        '调用工厂方法,创建接口
        iDalObject = factoryObject.CreateUser()

        '定义数据库表变量,接受IDAL接口层返回值
        ' Dim inflence As New Integer
        ' Dim inflence1 As New Integer

        '调用D层中实现接口的方法,并获取其返回值
        table = iDalObject.SelectUser(UserInfo, table)

        '判断是否有记录,有返回true,否则返回false
        If Not table Is Nothing Then '首先判断是否为空,不为空的情况下才能判断是否有记录
            If table.Rows.Count = 0 Then
                mylist.Add(False)
            Else
                mylist.Add(True)
                mylist.Add(table)
            End If
        Else
            mylist.Add(False)
        End If
        Return mylist
    End Function
End Class

  7)、Facade

'/**************************
'类名称: Facade
'命名空间: Facade
'创建时间: 2017/3/9 17:01:21
'作者: 连迎迎
'小组: 
'修改时间: 
'修改人: 
'版本号: 
'/***************************
Imports BLL
Imports Entity

Public Class LoginFacade
    Dim bllObject As New BLL.LoginUser
    Public Function OnInterfaceUser(ByVal UserInfo As Entity.User) As ArrayList
        '实例化B层对象
        '通过Facade层将ENtity传递给B层
        Return bllObject.isUserExist(UserInfo)
    End Function
End Class

  8)、UI

Imports System.Configuration
Imports System.Timers.Timer

Public Class LoginUI
    Public mylist As New ArrayList

    Private Sub btnOk_Click(sender As Object, e As EventArgs) Handles btnOk.Click
        '实例化实体曾UserInfor对象,用于在各层之间船体数据
        Dim UserInfo As New Entity.User
        '定义变量接受Facade层的返回值
        Dim facadeObject As New Facade.LoginFacade
        '判断用户名或密码是否输入
        If (txtPassword.Text = "" Or txtUsername.Text = "") Then
            MessageBox.Show("请输入用户名或密码")
            Exit Sub
        End If

        '赋值给user实体
        UserInfo.UserId = txtUsername.Text.Trim()
        UserInfo.Password = txtPassword.Text.Trim()

        '通过U层将entigyObject传递给Facade层
        mylist = facadeObject.OnInterfaceUser(UserInfo)
        If mylist.Count = 1 Then
            MessageBox.Show("用户名或密码错误!", "温馨提示")
            txtUsername.Text = ""
            txtPassword.Text = ""
            txtUsername.Focus()
        Else
            Me.Hide()
            'MessageBox.Show("登陆成功")
            MainUI.Show()
        End If
    End Sub
End Class

  【三】小结

           研究了这么久之后感觉自己柳暗花明了很多,知道很多自己不知道的地方,也体会到了思想通万事通的感觉,因为很多思维方面的理解无法全部都写出来给大家看,但还是希望这篇博客能给大家带来帮助,尽量的不要看我的代码,多看看代码之外的字。↖(^ω^)↗

评论 36
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值