室计费系统。更纠结的特点是组合查询。但代码做更多,且多为重复的代码,正是由于这个,它比较适合的模板方法模式。

一、基本介绍

模版方式模式是定义一个操作中的算法的骨架,而将步骤延迟到子类中。

模板方法使得子类能够不改变一个算法的结构就可以重定义算法的某些特定步骤。

类图

  

二、详细实现

1、建立模板父窗口

加入Windows窗口,设计模板界面(例如以下图),并在模板窗口里写入抽象出来的类和方法的代码。

'*************************************************
'作者:崔晓光
'小组:
'说明:组合查询模板
'创建日期:2014.9.9
'版本:
'**********************************************/
Imports Entity
Imports Microsoft.Office.Interop.Excel
Imports Microsoft.Office.Interop
Imports System.Data
Imports System.IO
'组合查询父窗口
Public Class FrmComQueryParent'实例化一个组合查询的实体Protected comQueryEntity As New ComQueryEntity’载入Protected Sub FrmComQueryParent_Load(sender As Object, e As EventArgs) Handles MyBase.Load'将參数传递给实体,赋初值'字段名comQueryEntity.CmbName1 = ""comQueryEntity.CmbName2 = ""comQueryEntity.CmbName3 = ""'操作符cmbMark1.Items.Add(">")cmbMark1.Items.Add("<")cmbMark1.Items.Add("=")cmbMark1.Items.Add("<>")cmbMark2.Items.Add(">")cmbMark2.Items.Add("<")cmbMark2.Items.Add("=")cmbMark2.Items.Add("<>")cmbMark3.Items.Add(">")cmbMark3.Items.Add("<")cmbMark3.Items.Add("=")cmbMark3.Items.Add("<>")'关系cmbRelation1.Items.Add("与")cmbRelation1.Items.Add("或")cmbRelation2.Items.Add("与")cmbRelation2.Items.Add("或")'窗口载入后,后两组查询默认不能用cmbName2.Enabled = FalsecmbName3.Enabled = FalsecmbMark2.Enabled = FalsecmbMark3.Enabled = FalsecmbRelation2.Enabled = FalsetxtContent2.Enabled = FalsetxtContent3.Enabled = FalseDim i As IntegerFor i = 0 To dgvRecord.Columns.Count - 1dgvRecord.Columns(i).Width = DataGridViewAutoSizeColumnMode.AllCells   '调整列宽为依据内容自己主动调整NextEnd Sub'查询Private Sub btQuery_Click(sender As Object, e As EventArgs) Handles btQuery.ClickTry'推断组合框不为空If cmbRelation1.Text = "" ThenIf cmbName1.Text = "" Or cmbMark1.Text = "" Or txtContent1.Text = "" ThenMsgBox("第一行查询条件不能为空,请完好查询信息!", CType(vbOKOnly + MsgBoxStyle.Exclamation, MsgBoxStyle), "提示")Exit SubEnd IfEnd IfIf cmbRelation1.Text <> "" ThenIf cmbName1.Text = "" Or cmbMark1.Text = "" Or txtContent1.Text = "" Or cmbName2.Text = "" Or cmbMark2.Text = "" Or txtContent2.Text = "" ThenMsgBox("所输入的查询条件不能为空。请完好查询信息。", CType(vbOKOnly + MsgBoxStyle.Exclamation, MsgBoxStyle), "提示")Exit SubEnd IfEnd IfIf cmbRelation2.Text <> "" ThenIf cmbName1.Text = "" Or cmbMark1.Text = "" Or txtContent1.Text = "" Or cmbName2.Text = "" Or cmbMark2.Text = "" Or txtContent2.Text = "" Or cmbName3.Text = "" Or cmbMark3.Text = "" Or txtContent3.Text = "" ThenMsgBox("所输入的查询条件不能为空,请完好查询信息!

", CType(vbOKOnly + MsgBoxStyle.Exclamation, MsgBoxStyle), "提示") Exit Sub End If End If '将參数传给实体 comQueryEntity.DbName = GetdbName() comQueryEntity.CmbName1 = ToEnglish(cmbName1.Text) comQueryEntity.CmbName2 = ToEnglish(cmbName2.Text) comQueryEntity.CmbName3 = ToEnglish(cmbName3.Text) comQueryEntity.CmbMark1 = cmbMark1.Text.Trim comQueryEntity.CmbMark2 = cmbMark2.Text.Trim comQueryEntity.CmbMark3 = cmbMark3.Text.Trim '在查询时非数字要加上'' If IsNumeric(txtContent1.Text) Then comQueryEntity.TxtContent1 = txtContent1.Text.Trim Else comQueryEntity.TxtContent1 = "'" & txtContent1.Text.Trim & "'" End If If IsNumeric(txtContent2.Text) Then comQueryEntity.TxtContent2 = txtContent2.Text.Trim Else comQueryEntity.TxtContent2 = "'" & txtContent2.Text.Trim & "'" End If If IsNumeric(txtContent3.Text) Then comQueryEntity.TxtContent3 = txtContent3.Text.Trim Else comQueryEntity.TxtContent3 = "'" & txtContent3.Text.Trim & "'" End If '前者还是后者 comQueryEntity.CmbRelation1 = ToEnglish(cmbRelation1.Text) comQueryEntity.CmbRelation2 = ToEnglish(cmbRelation2.Text) Dim dt As New Data.DataTable Dim facadeGeneral As New Facade.Facade.FacadeGeneral ' 把表显示到datagridview中 Call Todgv(comQueryEntity) Catch ex As Exception MsgBox(ex.Message) End Try End Sub ''' <summary> ''' 模板方法,定义虚函数ToEnglish,查询字段转化为数据库字段 ''' </summary> ''' <param name="cmbName"></param> ''' <returns></returns> ''' <remarks></remarks> Public Overridable Function ToEnglish(cmbName As String) As String Return "" End Function ''' <summary> ''' 获得数据库表名 ''' </summary> ''' <returns></returns> ''' <remarks></remarks> Protected Overridable Function GetdbName() As String Return "" End Function ''' <summary> ''' 把表显示到datagridview中 ''' </summary> ''' <remarks></remarks> Protected Overridable Sub Todgv(ByVal comQueryEntity As ComQueryEntity) End Sub ''' <summary> ''' 拼接字符串 ''' </summary> ''' <param name="frm"></param> ''' <returns></returns> ''' <remarks></remarks> Public Function Query(frm As FrmComQueryParent, ByVal comQueryEntity As ComQueryEntity) As String Dim cmdText As String = "" & frm.ToEnglish(frm.cmbName1.Text) & frm.cmbMark1.Text & "" & comQueryEntity.TxtContent1 & "" '非组合查询 If frm.cmbRelation1.Text = "" Then cmdText = cmdText '关系2为空,关系1不为空 ElseIf frm.cmbRelation2.Text = "" Then cmdText = cmdText & frm.ToEnglish(frm.cmbRelation1.Text) & "" & frm.ToEnglish(frm.cmbName2.Text) & frm.cmbMark2.Text & "" & comQueryEntity.TxtContent2 & "" Else '关系1,2都不为空 cmdText = cmdText & frm.ToEnglish(frm.cmbRelation1.Text) & "" & _ frm.ToEnglish(frm.cmbName2.Text) & frm.cmbMark2.Text & "'" & comQueryEntity.TxtContent2 & "'" & "" & _ frm.ToEnglish(frm.cmbRelation2.Text) & "" & _ frm.ToEnglish(frm.cmbName3.Text) & frm.cmbMark3.Text & "'" & comQueryEntity.TxtContent3 & "'" End If Return cmdText End Function ''' <summary> ''' 第一个组合关系是否为空 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> ''' <remarks></remarks> Private Sub cmbRelation1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cmbRelation1.SelectedIndexChanged If cmbRelation1.Text = "" Then cmbName2.Enabled = False cmbName3.Enabled = False cmbMark2.Enabled = False cmbMark3.Enabled = False cmbRelation2.Enabled = False txtContent2.Enabled = False txtContent3.Enabled = False Else cmbName2.Enabled = True cmbMark2.Enabled = True cmbRelation2.Enabled = True txtContent2.Enabled = True End If End Sub ''' <summary> ''' 第二个组合关系是否为空 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> ''' <remarks></remarks> Private Sub cmbRelation2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cmbRelation2.SelectedIndexChanged If cmbRelation2.Text = "" Then cmbName3.Enabled = False cmbMark3.Enabled = False txtContent3.Enabled = False Else cmbName3.Enabled = True cmbMark3.Enabled = True txtContent3.Enabled = True End If End Sub ''' <summary> ''' 关闭该窗口 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> ''' <remarks></remarks> Private Sub btCancel_Click(sender As Object, e As EventArgs) Handles btCancel.Click Me.Close() End Sub '导出为Excel Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click '要先加入引用才干用到 Microsoft.Office.Interop.Excel.Application() Dim MyExcel As New Microsoft.Office.Interop.Excel.Application() MyExcel.Application.Workbooks.Add(True) MyExcel.Visible = True '去除dgvRecord的编号列(这里也能够不要) Dim m As Integer For m = 0 To dgvRecord.ColumnCount - 1 MyExcel.Cells(1, m + 1) = Me.dgvRecord.Columns(m).HeaderText Next m '往excel表里加入数据 Dim i As Integer For i = 0 To Me.dgvRecord.RowCount - 1 Dim j As Integer For j = 0 To dgvRecord.ColumnCount - 1 If Me.dgvRecord(j, i).Value Is System.DBNull.Value Then MyExcel.Cells(i + 2, j + 1) = "" Else MyExcel.Cells(i + 2, j + 1) = dgvRecord(j, i).Value.ToString End If Next j Next i End Sub End Class

2、建立子窗口

例如以下图建立子窗口,选择继承创建的父窗口模板,然后就能够得到一模一样的子窗口了。

通过在子窗口里重写一些方法和类,以实现不同的功能就能够了。

实现上机学生查询的代码例如以下:

'*************************************************
'作者:崔晓光
'小组:
'说明:学生上机组合查询
'创建日期:2014.9.9
'版本:
'**********************************************/ Imports Entity.Entity
Imports Entity'学生正在上机查询
Public Class FrmComQueryStudentOn''' <summary>  ''' 载入combo的item  ''' </summary>  ''' <param name="sender"></param>  ''' <param name="e"></param>  ''' <remarks></remarks>  Private Sub FrmComQueryStudentOn_Load(sender As Object, e As EventArgs) Handles MyBase.LoadcmbName1.Items.Add("卡号")cmbName1.Items.Add("上机日期")cmbName1.Items.Add("上机时间")cmbName1.Items.Add("机器名")cmbName2.Items.Add("卡号")cmbName2.Items.Add("上机日期")cmbName2.Items.Add("上机时间")cmbName2.Items.Add("机器名")cmbName3.Items.Add("卡号")cmbName3.Items.Add("上机日期")cmbName3.Items.Add("上机时间")cmbName3.Items.Add("机器名")End Sub''' <summary>  ''' 把载入的汉字转换成数据库的字段  ''' </summary>  ''' <param name="cmbName"></param>  ''' <returns></returns>  ''' <remarks></remarks>  Public Overrides Function ToEnglish(cmbName As String) As StringSelect Case cmbNameCase "卡号"ToEnglish = "cardId"Case "上机日期"ToEnglish = "onDate"Case "上机时间"ToEnglish = "onTime"Case "机器名"ToEnglish = "local"Case "与"ToEnglish = " and "Case "或"ToEnglish = " or "Case ElseToEnglish = ""End SelectEnd Function''' <summary>  ''' 传数据库表名  ''' </summary>  ''' <returns></returns>  ''' <remarks></remarks>  Protected Overrides Function GetdbName() As StringReturn "LineRecord_Info"End Function''' <summary>  ''' 查询并把数据显示到datagridview中  ''' </summary>  ''' <remarks></remarks>  Protected Overrides Sub Todgv(ByVal comQueryEntity As ComQueryEntity)Dim returnList As New List(Of LineRecordEntity)        '实例化集合,用来返回实体类Dim frmComQueryParent As New FrmComQueryParent         '实例化父窗口Dim facadeComQuery As New Facade.FacadeComQuery        '实例化外观TrycomQueryEntity.SqlString = frmComQueryParent.Query(Me, comQueryEntity)   '获得拼接字符串returnList = facadeComQuery.QueryStudentOn(comQueryEntity)           '调用外观进行查询'取出返回的实体Dim lineRecordEntity As LineRecordEntityDim dataTable As New Data.DataTabledataTable.Columns.Add("卡号")          '自己主动创建列dataTable.Columns.Add("上机日期")dataTable.Columns.Add("上机时间")dataTable.Columns.Add("机器名")Dim dataNewRow As DataRow   '声明一个新行For i = 0 To returnList.Count - 1lineRecordEntity = returnList.Item(i)dataNewRow = dataTable.NewRow()'显示数据dataNewRow.Item(0) = lineRecordEntity.CardIddataNewRow.Item(1) = lineRecordEntity.OnDatedataNewRow.Item(2) = lineRecordEntity.OnTimedataNewRow.Item(3) = lineRecordEntity.LocaldataTable.Rows.Add(dataNewRow)           '将新行插入到表中Next'绑定数据源dgvRecord.AutoGenerateColumns = True           '自己主动创建列dgvRecord.AllowUserToAddRows = FalseMe.dgvRecord.DataSource = dataTable              '显示信息Me.dgvRecord.Refresh()Catch ex As ExceptionMsgBox(ex.Message)End TryEnd Sub
End Class

3.DAL层。详细的查询

我们尽管传的是实体。但实际上是一个字符串。所以在D层,仅仅要将字符串拼接起来即可

        ''' <summary>''' 从表中查询学生上机信息,组合查询''' </summary>''' <param name="comQueryEntity">上机记录实体</param>Public Function QueryOn(ByVal comQueryEntity As Entity.ComQueryEntity) As List(Of Entity.Entity.LineRecordEntity) Implements ILineRecord.QueryOnTrystrSql = "select * from (select * from LineRecord_Info where offStatus='正在上机')as LineRecord_Info where " & comQueryEntity.SqlString.TrimdataTable = sqlHelper.ExecSelectNo(CommandType.Text, strSql)Dim returnList As New List(Of LineRecordEntity)Dim lineRecordEntity As New LineRecordEntity'封装查到的实体For i = 0 To dataTable.Rows.Count - 1lineRecordEntity.CardId = dataTable.Rows(i).Item(0).ToStringlineRecordEntity.OnDate = dataTable.Rows(i).Item(1).ToStringlineRecordEntity.OnTime = dataTable.Rows(i).Item(2).ToStringlineRecordEntity.Local = dataTable.Rows(i).Item(8).ToStringreturnList.Add(lineRecordEntity)NextReturn returnListCatch ex As ExceptionThrowEnd TryEnd Function

三、总结

自此,模版方法模式已经做完。

这里注意的是组合查询的查询语句的方式。详见

机房收费系统 之 组合查询BUG。

模版方法的核心就是将总体架构抽象到父类中,详细的时间情况由子类拓展。在我们学习生活中也是,学者去抽象,去总结。因此,提升能力水平。

版权声明:本文博客原创文章,博客,未经同意,不得转载。

模板方法模式的房间改造-组合查询相关推荐

  1. 设计模式(三):模板方法模式、迭代器和组合模式、状态模式

    八.模板方法模式 1.概念 模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤. 模板就是一个方法,更具体地说 ...

  2. 模板方法模式实现组合查询

    1.前提 1.模板方法模式 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 2.组合方法 之前写过一篇博客,讲述实现任意 ...

  3. .NET重构(四):窗体继承+模板方法,完美实现组合查询

    导读:在机房重构中,有好些个查询都是大同小异,最为显著的就是组合查询了.怎样给自己省事儿,相同的东西能不能重复利用,就成了一个现实的问题.第一遍做机房的时候,使用的更多的是:复制+粘贴.学习了设计模式 ...

  4. 学妹惊呼:使用Java8改造后的模板方法模式真的是yyds

    △Hollis, 一个对Coding有着独特追求的人△ 这是Hollis的第 371 篇原创分享 作者 l Hollis 来源 l Hollis(ID:hollischuang) 我们在日常开发中,经 ...

  5. 继承窗体搭建组合查询模板方法的幸福之家

            窗外寒冬有了春的温暖,过了立春还在北国,总觉得已过春节,实际迟迟未到.         继承窗体做了组合查询与模板方法的红娘,搭建了幸福之间.期盼着春节列车红娘,只想做南方过客的&qu ...

  6. 页面多条件组合查询功能 代码 如何写效率高_Jeecg Boot 2.2 首个里程碑版本发布,低代码平台

    项目介绍 JeecgBoot是一款基于代码生成器的低代码开发平台,开源界"小普元"超越传统商业企业开发平台!采用前后端分离架构:SpringBoot 2.x,Ant Design& ...

  7. 组合查询(机房重构知识点总结)

    历经n多天.组合查询模板最终做完了,总结一下这几天的成果.和大家一起学习交流. 先看一下父窗口的关键代码: 父窗口代码: Public Class frmComboQueryProtected Ove ...

  8. 在一个程序设计里,不同的功能窗口有着相似的功能实现方式,可采用设计模式---模板方法模式

        前段时间学习了一些设计模式,最近在做项目的过程中恰巧用到了其中的一个--模板方法模式.这个模式在程序设计过程中可是为小编省去了不少的代码量呢.具体是怎样应用的呢?接下来小编为您分享. 前面博文 ...

  9. java tea bag_设计模式系列教程—Template Method Pattern(模板方法模式)

    9 Template Method Pattern(模板方法模式) 前言:封装步骤的算法. Vander作为老板,凡是亲力亲为,他新开了家咖啡店,这是他招牌咖啡卡布奇诺的冲泡方法: 1.把水煮沸 2. ...

  10. 设计模式学习(八) 模板方法模式

    引入 定义:在一个方法中定义了一个算法的骨架,而将一些一些步骤延迟到子类中.模板方法使得子类可以在不改变算法接口的情况下,重新定义算法中的某些步骤. uml类图 这个模式是用来创建一个算法的模板,什么 ...

最新文章

  1. 获取Linux/Unix文件系统信息
  2. mysql存储家庭成员信息_家谱管理系统的设计与实现(MyEclipse,MySQL)
  3. 为你的程序添加监听器
  4. python selenium 保存网页_python selenium+pywin32 实现网页另存为
  5. linux查找应用主机,Linux 主机和服务器基本性能检查命令和工具
  6. python接口自动化(二十五)--unittest断言——下(详解)
  7. python生成动态二维码实例_python生成动态个性二维码(示例代码)
  8. JavaWeb无限级分销结构分析
  9. leetcode算法—两数相加 Add Two Numbers
  10. JSOI2018冬令营游记总结(迁移自洛谷博客)
  11. 关于web.xml 中的 welcome-file-list 的认识
  12. [SPLEB]CodeSmith原理剖析(2)
  13. 华硕固件默认ip,新路由3 newifi d2刷机刷华硕固件教程
  14. 用PYTHON优化投资组合的配置
  15. 数据库锁的分类(粒度,级别)
  16. Android 如何通过拨号盘暗码启动你的应用
  17. 关于数独--九宫格的算法实现
  18. 如何成为一名优秀员工
  19. IDAFicator / OllyDBG Plug-in by Zool@nder|AT4RE
  20. set off 和 set out 的区别

热门文章

  1. vue 使用 ueditor uparse_vue手把手教学~搭建web聊天室
  2. php手术多久就不疼了,自己腹部刚开刀口没几天,却站了5小时为患者手术
  3. it技术交流平台_IT协会向你招手了,不了解了解?
  4. 外星人电脑为什么那么贵_为什么系统门窗那么贵?
  5. 你不能访问此文件夹,因为你组织的安全策略阻止了未经身份验证的来宾访问
  6. AndroidStudio 文件目录如何“刷新”
  7. Flink 集群搭建
  8. bzoj4571: [Scoi2016]美味
  9. HTMLCSS学习笔记(三)----标签类型转换、样式重置
  10. 《那些年啊,那些事——一个程序员的奋斗史》——26