走在机房重构的路上之组合查询

            做完第一遍机房后对组合查询有种心有余悸的感觉,但这次有设计模式来帮我们就不用在害怕了。在机房收费中有三个组合查询的窗体,它们的外表一样,只是各自的下拉框中的内容不一样,所以从设计模式中来讲模板模式就能解决这个难题。

            所谓模板就像是我们折纸一样,有一个参照物,做出来的成品就相当于对参照物的复制品。所以这里的组合查询就需要一个父类窗体:用来承载所有的控件和代码中需要用到的方法,“子”窗体就来继承并且对一些方法进行重写,完成自己的特殊化构造,那么先来看窗体的建造过程:

          先将一个具有基本骨架的窗体建立好,我在这里命名为frmGroupQuery。其中有用到的方法:GetEnglish(用来将字段名转换为对应的英文名称,同数据库中字段名一致),GetTable(每个窗体获取各自需要的数据库名称);如下图所示:

       走在机房重构的路上之组合查询_第1张图片

         其中代码:可以看做是对每个窗体的代码进行提取公因式的操作。

Imports Facade.FadGroupQuery
Public Class frmGroupQuery
    Public groupQuery As New Model.GroupQueryModel     '定义一个实体参数
    '主要是用来判断界面的控件中是否已经填入数据
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btnQuery.Click
        '第一行组合关系为空
        If cbxRelation1.Text = "" Then
            If cbxString1.Text = "" Then
                MsgBox("请输入字段名")
            ElseIf cbxOperate1.Text = "" Then
                MsgBox("请输入操作符")
            ElseIf txtQuery1.Text = "" Then
                MsgBox("请输入要查询的内容")
            End If
        End If

        '当第一个组合关系不为空时,就要求前两行的文本都不为空,所以要一一进行判断
        If cbxRelation1.Text <> "" Then
            If cbxString1.Text = "" Then
                MsgBox("请输入字段名")
            ElseIf cbxOperate1.Text = "" Then
                MsgBox("请输入操作符")
            ElseIf txtQuery1.Text = "" Then
                MsgBox("请输入查询内容")
            ElseIf cbxString2.Text = "" Then
                MsgBox("请输入字段名")
            ElseIf cbxOperate2.Text = "" Then
                MsgBox("请输入操作符")
            ElseIf txtQuery2.Text = "" Then
                MsgBox("请输入查询内容")
            End If
        End If


        '当第二个组合关系不为空时
        If cbxRelation2.Text <> "" Then
            If cbxString1.Text = "" Then
                MsgBox("请输入字段名")
            ElseIf cbxOperate1.Text = "" Then
                MsgBox("请输入操作符")
            ElseIf txtQuery1.Text = "" Then
                MsgBox("请输入查询内容")
            ElseIf cbxString2.Text = "" Then
                MsgBox("请输入字段名")
            ElseIf cbxOperate2.Text = "" Then
                MsgBox("请输入操作符")
            ElseIf txtQuery2.Text = "" Then
                MsgBox("请输入查询内容")
            ElseIf cbxString2.Text = "" Then
                MsgBox("请输入字段名")
            ElseIf cbxOperate2.Text = "" Then
                MsgBox("请输入操作符")
            ElseIf txtQuery2.Text = "" Then
                MsgBox("请输入查询内容")
            ElseIf cbxString3.Text = "" Then
                MsgBox("请输入字段名")
            ElseIf cbxOperate3.Text = "" Then
                MsgBox("请输入操作符")
            ElseIf txtQuery3.Text = "" Then
                MsgBox("请输入查询内容")
            End If
        End If

        Dim MgroupQuery As New Model.GroupQueryModel
        MgroupQuery.cbxString1 = GetEnglish(cbxString1.Text.Trim())
        MgroupQuery.cbxString2 = GetEnglish(cbxString2.Text.Trim())
        MgroupQuery.cbxString3 = GetEnglish(cbxString3.Text.Trim())
        MgroupQuery.cbxOperate1 = cbxOperate1.Text.Trim
        MgroupQuery.cbxOperate2 = cbxOperate2.Text.Trim
        MgroupQuery.cbxOperate3 = cbxOperate3.Text.Trim
        MgroupQuery.txtQuery1 = txtQuery1.Text
        MgroupQuery.txtQuery2 = txtQuery2.Text
        MgroupQuery.txtQuery3 = txtQuery3.Text
        MgroupQuery.cbxRelation1 = GetEnglish(cbxRelation1.Text.Trim)
        MgroupQuery.cbxRelation2 = GetEnglish(cbxRelation2.Text.Trim)
        MgroupQuery.gettable = GetTable()

        '实例化外观层
        Dim fadGroups As New Facade.FadGroupQuery
        '定义一个载体
        Dim endResult As New DataTable
        '获取从外观层传出的数据值
        endResult = fadGroups.F_GroupQuery(MgroupQuery)
        '将传到载体中的数据传达给控件,显示在控件中
        dtGroupQuery.DataSource = endResult

    End Sub

    Private Sub frmGroupQuery_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        '操作符内容的加载
        cbxOperate1.Items.Add(">")
        cbxOperate1.Items.Add("<")
        cbxOperate1.Items.Add("=")

        cbxOperate2.Items.Add(">")
        cbxOperate2.Items.Add("<")
        cbxOperate2.Items.Add("=")

        cbxOperate3.Items.Add(">")
        cbxOperate3.Items.Add("<")
        cbxOperate3.Items.Add("=")

        '组合关系
        cbxRelation1.Items.Add("与")
        cbxRelation1.Items.Add("或")
        cbxRelation2.Items.Add("或")
        cbxRelation2.Items.Add("与")

        '控件的可用性:窗体加载时,第二行、第三行以及第二个组合关系都不能用
        cbxOperate2.Enabled = False
        cbxOperate3.Enabled = False
        txtQuery2.Enabled = False
        txtQuery3.Enabled = False
        cbxString2.Enabled = False
        cbxString3.Enabled = False
        cbxRelation2.Enabled = False
    End Sub
    '声明一个函数用来将控件中的文字转换为数据库中需要的英文字段名
    Protected Overridable Function GetEnglish(cbxString As String) As String
        Return ""
    End Function

    Public Overridable Function GetTable() As String
        Return ""
    End Function

    Private Sub cbxRelation1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cbxRelation1.SelectedIndexChanged
        '只有当第一个关系选择不为空才能使第二行的控件enabled
        cbxRelation2.Enabled = True
        cbxOperate2.Enabled = True
        cbxString2.Enabled = True
        txtQuery2.Enabled = True
    End Sub

    Private Sub cbxRelation2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cbxRelation2.SelectedIndexChanged
        cbxOperate3.Enabled = True
        cbxString3.Enabled = True
        txtQuery3.Enabled = True
    End Sub

    Private Sub btnOutPut_Click(sender As Object, e As EventArgs) Handles btnOutPut.Click

    End Sub
End Class

           父类窗体设计好后,开始设计子窗体,让三个“子”从“父”那里继承自己该有的东西;

走在机房重构的路上之组合查询_第2张图片

点击“添加”后会出现下面的窗口:

      走在机房重构的路上之组合查询_第3张图片

              这样,子类窗体对父类的继承就完成了,相比较而言,子类窗体的各个控件都加上了一把锁,也就是不能修改,能修改的只是对父类中方法和加载的东西进行重写,说白了就是一种个性化的设置,比如学生个人信息维护:

               走在机房重构的路上之组合查询_第4张图片

               像这张图中显示的,父类窗体都只是给定一个基本框架,然后该窗体对它进行个性化:combox加载出自己需要显示的,GetEnglish函数转换自己对应的数据库:T_StuInfo中的字段名,GetTable调取T_StuInfo中的数据。

                然而需要重写的只是U层的代码,其他层都和父类窗体使用一样的代码,也就是包括父类窗体在内的四个窗体都调取同一个B、D、IDAL、Factory。这里主要是B层和D层的代码:

B层:

Public Class GroupQueryBLL
    Public Function GroupQuery(ByVal groups As Model.GroupQueryModel) As DataTable
        Dim IGroupQuery As IDAL.IGroupQuery
        Dim factory As New Factory.LoginFacy
        IGroupQuery = factory.CreateGroupQuery
        Dim table As New DataTable
        table = IGroupQuery.GroupQuery(groups)
        If Not IsNothing(table) Then
            Return table
        Else
            MsgBox("没有查到相关数据")
            Return Nothing
        End If
    End Function
End Class


D层:

   

Imports IDAL
Imports System.Data
Imports System.Data.SqlClient
Public Class GroupQueryDAL : Implements IDAL.IGroupQuery
    Public Function GroupQuery(groups As Model.GroupQueryModel) As DataTable Implements IGroupQuery.GroupQuery
        Dim cmdText As String = "PROC_GroupQuery"
        Dim sqlparams As SqlParameter() = {New SqlParameter("@cbxString1", groups.cbxString1), New SqlParameter("@cbxString2", groups.cbxString2), New SqlParameter("@cbxString3", groups.cbxString3), New SqlParameter("@cbxOperate1", groups.cbxOperate1), New SqlParameter("@cbxOperate2", groups.cbxOperate2), New SqlParameter("@cbxOperate3", groups.cbxOperate3), New SqlParameter("@txtQuery1", groups.txtQuery1), New SqlParameter("@txtQuery2", groups.txtQuery2), New SqlParameter("@txtQuery3", groups.txtQuery3), New SqlParameter("@gettable", groups.gettable), New SqlParameter("@cbxRelation1", groups.cbxRelation1), New SqlParameter("@cbxRelation2", groups.cbxRelation2)}
        Dim helper As New SqlHelper
        Dim table As New DataTable

        table = helper.ExecSelect(cmdText, CommandType.StoredProcedure, sqlparams)

        If table.Rows.Count <> 0 Then
            Return table
        Else
            Return Nothing
        End If
    End Function
End Class

             值得注意的是:由于这层用到的存储过程所以sqlparams中不再是cmdType,而是commandType.StoreProcedures 。

             提到存储过程,存储过程就是对一堆sql语句的封装和集结,为了省去过多的sql语句,所以使用存储过程,下面就是存储过程的语句:

走在机房重构的路上之组合查询_第5张图片

           现在组合查询的大部分都在这里了,虽然组合查询的功能实现了,但是有一个地方我一直不明白,在父类的U层中有这么几行代码:

走在机房重构的路上之组合查询_第6张图片

             这段代码是将控件中的值进行存储传递的过程,框中的是组合关系,按理说这里是应该有GetEnglish函数,毕竟组合关系控件中的文本也是汉语,但是有几个同学的都没有这个函数却都能行通,而我的如果没有这个函数那就出现下面的结果:

   走在机房重构的路上之组合查询_第7张图片

                  难道是VS2012和2013的区别???有待探究。。。。

              也许这里的代码不是多精简,但凡事一步一个脚印,努力去做,做得多了也就知道哪些可以合并封装了,如果有什么不对的地方欢迎大家指正。

你可能感兴趣的:(重构,存储)