【机房重构】——模板方法解决组合查询

来源:互联网 发布:香港 知乎 编辑:程序博客网 时间:2024/05/01 03:43

     引言

  在机房重构再次遇到组合查询的时候非常的兴奋,这是因为在学习VB.NET的时候写过名为《vb.net——窗体继承》的博客,当我在谋划组合查询的时候看到完全的四个窗体就立马想到了这个知识,当时还不知道这是个设计模式,当学完了设计模式之后因为没有进行实践,所以第一反应不是设计模式而是自己写过的博客,这样凸显了博客的作用,但是现在知道了这是一种设计模式,就在接下来对这个模式进行小结一下。

  理论部分

  模板方法:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法结构即可重定义该算法的某些特定的步骤。
  类图:
                
  优点:模板方法是通过把不变行为搬移到超类,去除子类中的重复代码类体现它的优势,这样就提供了一个很好的代码复用平台,大大的提高了效率。

 实践部分

 在上面介绍了一些关于模板方法的基本知识,下面就结合机房收费系统中的组合查询来对模板方法小试一把。
 首先在U层创建一个父窗体:
          
 下面来看一下我们父窗体中的基本代码:
  '定义一个保护类型 的变量,子窗体也可以访问    Protected groupcheck As Entity.EN_GoupCheck = New Entity.EN_GoupCheck()    Private Sub frmGoupCheck_Load(sender As Object, e As EventArgs) Handles MyBase.Load        '操作符部分,因为操作符不变,所以在父窗体中加载        cobOperator1.Items.Add(">")        cobOperator1.Items.Add("<")        cobOperator1.Items.Add("=")        cobOperator1.Items.Add("<>")        cobOperator2.Items.Add(">")        cobOperator2.Items.Add("<")        cobOperator2.Items.Add("=")        cobOperator2.Items.Add("<>")        cobOperator3.Items.Add(">")        cobOperator3.Items.Add("<")        cobOperator3.Items.Add("=")        cobOperator3.Items.Add("<>")        '关系        cobRelations1.Items.Add("与")        cobRelations1.Items.Add("或")        'cobRelations1.Items.Add("")        cobRelations2.Items.Add("与")        cobRelations2.Items.Add("或")        'cobRelations2.Items.Add("")        '在加载的时候,只有第一行控件可用,后两行控件不可用        cobFieldName2.Enabled = False        cobFieldName3.Enabled = False        cobOperator2.Enabled = False        cobOperator3.Enabled = False        cobRelations2.Enabled = False        txtContent2.Enabled = False        txtContent3.Enabled = False        '当我们选中dgvRecordz控件就选中行         dgvRecord.SelectionMode = DataGridViewSelectionMode.FullRowSelect        Dim i As Integer        For i = 0 To dgvRecord.Columns.Count - 1            dgvRecord.Columns(i).Width = DataGridViewAutoSizeColumnsMode.AllCells        Next    End Sub    ''' <summary>    ''' 清空查询条件和结果    ''' </summary>    ''' <param name="sender"></param>    ''' <param name="e"></param>    ''' <remarks></remarks>    Private Sub btClear_Click(sender As Object, e As EventArgs) Handles btClear.Click        cobFieldName1.Text = ""        cobFieldName2.Text = ""        cobFieldName3.Text = ""        cobOperator1.Text = ""        cobOperator2.Text = ""        cobOperator3.Text = ""        txtContent1.Text = ""        txtContent2.Text = ""        txtContent3.Text = ""        cobRelations1.Text = ""        cobRelations2.Text = ""        dgvRecord.ClearSelection()    End Sub    ''' <summary>    ''' 退出    ''' </summary>    ''' <param name="sender"></param>    ''' <param name="e"></param>    ''' <remarks></remarks>    Protected Sub btQuit_Click(sender As Object, e As EventArgs) Handles btQuit.Click        Me.Dispose()    End Sub    ''' <summary>    ''' 查询按钮    ''' </summary>    ''' <param name="sender"></param>    ''' <param name="e"></param>    ''' <remarks></remarks>    Protected Sub btCheck_Click(sender As Object, e As EventArgs) Handles btCheck.Click        '判断组合框不为空          If cobRelations1.Text = "" Then            If cobFieldName1.Text = "" Or cobOperator1.Text = "" Or txtContent1.Text = "" Then                MsgBox("第一行查询条件不能为空")                Exit Sub            End If        End If        If cobRelations1.Text <> "" Then            If cobFieldName2.Text = "" Or cobOperator2.Text = "" Or txtContent2.Text = "" Then                MsgBox("第二行查询条件不能为空")                Exit Sub            End If        Else            If cobRelations2.Text <> "" Then                If cobFieldName1.Text = "" Or cobOperator1.Text = "" Or txtContent1.Text = "" Or                cobFieldName2.Text = "" Or cobOperator1.Text = "" Or txtContent2.Text = "" Or                cobFieldName3.Text = "" Or cobOperator1.Text = "" Or txtContent3.Text = "" Then                    MsgBox("第三行查询条件不能为空")                    Exit Sub                End If            End If        End If        '给实体赋值        groupcheck.GetdbName = GetdbName()        groupcheck.CobFieldName1 = ToEnglish(cobFieldName1.Text)        groupcheck.CobFieldName2 = ToEnglish(cobFieldName2.Text)        groupcheck.CobFieldName3 = ToEnglish(cobFieldName3.Text)        groupcheck.cobOperator1 = cobOperator1.Text.Trim        groupcheck.cobOperator2 = cobOperator2.Text.Trim        groupcheck.cobOperator3 = cobOperator3.Text.Trim        groupcheck.txtContent1 = txtContent1.Text.Trim        groupcheck.txtContent2 = txtContent2.Text.Trim        groupcheck.txtContent3 = txtContent3.Text.Trim        ''前者还是后者          groupcheck.cobRelations1 = ToEnglish(cobRelations1.Text)        groupcheck.cobRelations2 = ToEnglish(cobRelations1.Text)        Dim dt As New DataTable        Dim Ugropcheck As New Facade.FacadeGroupCheck        dt = Ugropcheck.FGroupCheck(groupcheck)        If (dt.Rows.Count = 0) Then            MsgBox("没有符合条件的记录")            Exit Sub        Else            Call Todgv()        End If    End Sub    ''' <summary>      ''' 因为每个窗体需要转换的字段的内容不同,所以定义虚函数ToEnglish,查询字段转化为数据库字段      ''' </summary>      ''' <param name="cboName"></param>      ''' <returns></returns>      ''' <remarks></remarks>      Public Overridable Function ToEnglish(cboName As String) As String        Return ""    End Function    ''' <summary>      ''' 获得数据库表名,在不同的窗体和不同的表交互    ''' </summary>      ''' <returns></returns>      ''' <remarks></remarks>      Public Overridable Function GetdbName() As String        Return ""    End Function    ''' <summary>      ''' 把表显示到datagridview中      ''' </summary>      ''' <remarks></remarks>      Protected Overridable Sub Todgv()        'dgvRecord.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells    End Sub       ''' <summary>    ''' 第一关系是否为空,判断第二三行是否可用    ''' </summary>    ''' <param name="sender"></param>    ''' <param name="e"></param>    ''' <remarks></remarks>    Protected Sub cobRelations1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cobRelations1.SelectedIndexChanged        If cobRelations1.Text = "" Then            cobFieldName2.Enabled = False            cobFieldName3.Enabled = False            cobOperator2.Enabled = False            cobOperator3.Enabled = False            cobRelations2.Enabled = False            txtContent2.Enabled = False            txtContent3.Enabled = False        Else            cobFieldName2.Enabled = True            cobOperator2.Enabled = True            cobRelations2.Enabled = True            txtContent2.Enabled = True        End If    End Sub    ''' <summary>    ''' 根据第二个关系,判断第三行的内容是否可用    ''' </summary>    ''' <param name="sender"></param>    ''' <param name="e"></param>    ''' <remarks></remarks>    Protected Sub cobRelations2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cobRelations2.SelectedIndexChanged        If cobRelations2.Text = "" Then            cobFieldName3.Enabled = False            cobOperator3.Enabled = False            txtContent3.Enabled = False        Else            cobFieldName3.Enabled = True            cobOperator3.Enabled = True            txtContent3.Enabled = True        End If    End SubEnd Class
当我们完成父窗体以后,下面来看子窗体(以操作员工作记录为例),首先添加子窗体(具体过程见文章开头链接博客):
 
 Public Overrides Function ToEnglish(cboName As String) As String        Select Case cboName            Case "教师"                ToEnglish = "UserID"            Case "上班日期"                ToEnglish = "LoginDate"            Case "上班时间"                ToEnglish = "LoginTime"            Case "下班日期"                ToEnglish = "LogoutDate"            Case "下班时间"                ToEnglish = "LogoutTime"            Case "机器名"                ToEnglish = "Computer"            Case "与"                ToEnglish = "and"            Case "或"                ToEnglish = "or"            Case Else                ToEnglish = ""        End Select    End Function    ''' <summary>      ''' 传数据库表名      ''' </summary>      ''' <returns></returns>      ''' <remarks></remarks>      Public Overrides Function GetdbName() As String        Return "ZH_WorkLogInfo"    End Function    ''' <summary>      ''' 把数据显示到datagridview中      ''' </summary>      ''' <remarks></remarks>      Protected Overrides Sub Todgv()        Dim dt As New DataTable        Dim frmGropCheck As New frmGroupCheck        Dim FacadeGroupCheck As New Facade.FacadeGroupCheck        Try            dt = FacadeGroupCheck.FGroupCheck(groupcheck)            If dt.Rows.Count = 0 Then                dt.Clear()                dgvRecord.DataSource = Nothing                dgvRecord.Refresh()            Else                dgvRecord.DataSource = dt                dgvRecord.Columns(0).Visible = False                dgvRecord.Columns(1).HeaderText = "教师"                dgvRecord.Columns(2).HeaderText = "上班日期"                dgvRecord.Columns(3).HeaderText = "上班时间"                dgvRecord.Columns(4).HeaderText = "下班日期"                dgvRecord.Columns(5).HeaderText = "下班时间"                dgvRecord.Columns(6).HeaderText = "机器名"                dgvRecord.Columns(7).HeaderText = "状态"            End If        Catch ex As Exception            MsgBox(ex.Message, vbOKOnly, "提示")        End Try    End Sub’调用模块中的方法,导出Excel表格    Private Sub btExportExcel_Click(sender As Object, e As EventArgs) Handles btExportExcel.Click        Call ExportExcel(Me, dgvRecord)    End SubEnd Class
以上就是我们U层的代码,可以看出在子窗体中最后多出了一个功能——导出Excel表格,这就是说子窗体继承父窗体以后,不能修改父窗体中的原有的控件,但是可以在原有的基础上添加新的功能。
 下面来看一下我D层的代码:
Public Function IGroupCheck(groupcheck As Entity.EN_GoupCheck) As DataTable Implements IGroupCheck.IGroupCheck        Dim sql As String        sql = "PROC_GroupCheck" '调用存储过程        Dim cmdType As CommandType = CommandType.StoredProcedure '类型为存储过程        '设置参数        Dim paras As SqlParameter() = {New SqlParameter("@cobFieldName1", groupcheck.CobFieldName1),                                       New SqlParameter("@cobFieldName2", groupcheck.CobFieldName2),                                       New SqlParameter("@cobFieldName3", groupcheck.CobFieldName3),                                       New SqlParameter("@cobOperator1", groupcheck.cobOperator1),                                       New SqlParameter("@cobOperator2", groupcheck.cobOperator2),                                       New SqlParameter("@cobOperator3", groupcheck.cobOperator3),                                       New SqlParameter("@txtContent1", groupcheck.txtContent1),                                       New SqlParameter("@txtContent2", groupcheck.txtContent2),                                       New SqlParameter("@txtContent3", groupcheck.txtContent3),                                       New SqlParameter("@cobRelations1", groupcheck.cobRelations1),                                       New SqlParameter("@cobRelations2", groupcheck.cobRelations2),                                       New SqlParameter("@tableName", groupcheck.GetdbName)}        Return SqlHelper.SqlHelper.ExecSelect(sql, cmdType, paras)    End Function
  因为我们需要和不同的数据库交互,开始的时候我想下U层写好字符串拼接的代码然后封装到实体中,然后通过实体传到D层和数据库交互,但是在实现了以后发现很不友好(自我感觉),所以就想换一种思路来实现这个功能,在我经过一天的学习后最后采用存储过程来实现代码见(存储过程和触发器)。
  为什么会有这种想法呢?因为每一个功能需要和不同的数据库表打交道,所以我想只用一个变量来控制我们和那张表交互,在网上查询这方面的知识的时候,提示用存储过程来试一试,这才有了存储过程的学习。

  小结

 用这种方法实现组合查询相比第一遍机房傻兮兮的重复画一样的窗体,复制一样的代码心里爽多了,当然在第一遍的时候实现了字符串的拼接也是很爽的,所以,我们在不同阶段应该尝试一些新的方法来实现我们的功能,虽然我们不一定能实现,单至少我们有了这样的想法,虽然我们用的并不一定完美,至少我们学到了新思路,学习就是在这样不断的思考,不断的尝试中提高的,希望在以后的学习中能不断的产生新的想法
   

1 0
原创粉丝点击