在机房重构再次遇到组合查询的时候非常的兴奋,这是因为在学习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层和数据库交互,但是在实现了以后发现很不友好(自我感觉),所以就想换一种思路来实现这个功能,在我经过一天的学习后最后采用存储过程来实现代码见(存储过程和触发器)。 为什么会有这种想法呢?因为每一个功能需要和不同的数据库表打交道,所以我想只用一个变量来控制我们和那张表交互,在网上查询这方面的知识的时候,提示用存储过程来试一试,这才有了存储过程的学习。 小结 用这种方法实现组合查询相比第一遍机房傻兮兮的重复画一样的窗体,复制一样的代码心里爽多了,当然在第一遍的时候实现了字符串的拼接也是很爽的,所以,我们在不同阶段应该尝试一些新的方法来实现我们的功能,虽然我们不一定能实现,单至少我们有了这样的想法,虽然我们用的并不一定完美,至少我们学到了新思路,学习就是在这样不断的思考,不断的尝试中提高的,希望在以后的学习中能不断的产生新的想法 总结
以上是内存溢出为你收集整理的【机房重构】——模板方法解决组合查询全部内容,希望文章能够帮你解决【机房重构】——模板方法解决组合查询所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)