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

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

引言


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


理论部分


模板方法:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法结构即可重定义该算法的某些特定的步骤。


类图:


20150107205333427.png

优点:模板方法是通过把不变行为搬移到超类,去除子类中的重复代码类体现它的优势,这样就提供了一个很好的代码复用平台,大大的提高了效率。


实践部分


在上面介绍了一些关于模板方法的基本知识,下面就结合机房收费系统中的组合查询来对模板方法小试一把。


首先在U层创建一个父窗体:



20150107210327515.png


下面来看一下我们父窗体中的基本代码


  '定义一个保护类型 的变量,子窗体也可以访问
    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 Sub
End 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层和数据库交互,但是在实现了以后发现很不友好(自我感觉),所以就想换一种思路来实现这个功能,在我经过一天的学习后最后采用存储过程来实现代码见(存储过程和触发器)。


为什么会有这种想法呢?因为每一个功能需要和不同的数据库表打交道,所以我想只用一个变量来控制我们和那张表交互,在网上查询这方面的知识的时候,提示用存储过程来试一试,这才有了存储过程的学习。


小结


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

目录
相关文章
|
4天前
|
弹性计算 运维 搜索推荐
三翼鸟携手阿里云ECS g9i:智慧家庭场景的效能革命与未来生活新范式
三翼鸟是海尔智家旗下全球首个智慧家庭场景品牌,致力于提供覆盖衣、食、住、娱的一站式全场景解决方案。截至2025年,服务近1亿家庭,连接设备超5000万台。面对高并发、低延迟与稳定性挑战,全面升级为阿里云ECS g9i实例,实现连接能力提升40%、故障率下降90%、响应速度提升至120ms以内,成本降低20%,推动智慧家庭体验全面跃迁。
|
4天前
|
数据采集 人工智能 自然语言处理
3分钟采集134篇AI文章!深度解析如何通过云无影AgentBay实现25倍并发 + LlamaIndex智能推荐
结合阿里云无影 AgentBay 云端并发采集与 LlamaIndex 智能分析,3分钟高效抓取134篇 AI Agent 文章,实现 AI 推荐、智能问答与知识沉淀,打造从数据获取到价值提炼的完整闭环。
375 91
|
5天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
5天前
|
SQL 人工智能 自然语言处理
Geo优化SOP标准化:于磊老师的“人性化Geo”体系如何助力企业获客提效46%
随着生成式AI的普及,Geo优化(Generative Engine Optimization)已成为企业获客的新战场。然而,缺乏标准化流程(Geo优化sop)导致优化效果参差不齐。本文将深入探讨Geo专家于磊老师提出的“人性化Geo”优化体系,并展示Geo优化sop标准化如何帮助企业实现获客效率提升46%的惊人效果,为企业在AI时代构建稳定的流量护城河。
385 156
Geo优化SOP标准化:于磊老师的“人性化Geo”体系如何助力企业获客提效46%
|
4天前
|
数据采集 缓存 数据可视化
Android 无侵入式数据采集:从手动埋点到字节码插桩的演进之路
本文深入探讨Android无侵入式埋点技术,通过AOP与字节码插桩(如ASM)实现数据采集自动化,彻底解耦业务代码与埋点逻辑。涵盖页面浏览、点击事件自动追踪及注解驱动的半自动化方案,提升数据质量与研发效率,助力团队迈向高效、稳定的智能化埋点体系。(238字)
267 156
|
12天前
|
机器人 API 调度
基于 DMS Dify+Notebook+Airflow 实现 Agent 的一站式开发
本文提出“DMS Dify + Notebook + Airflow”三位一体架构,解决 Dify 在代码执行与定时调度上的局限。通过 Notebook 扩展 Python 环境,Airflow实现任务调度,构建可扩展、可运维的企业级智能 Agent 系统,提升大模型应用的工程化能力。