经过第一遍机房收费系统中组合查询的实现,我们都知道组合查询中的代码比较多,而且大部分都是重复的,再一次机房收费,我们需要不断改进,避免重复代码,这时我们想到了设计模式中的模板方法。
还记得刚开始小菜跟大鸟讲的故事--考题抄错也白搭,每个学生都要抄一遍题然后写答案,题抄错了,答案自然就错了,为了避免这种情况,想到了老师出一份试卷,打印多份,学生填写答案就ok,这就相当于我们的模板方法模式。
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
AbstractClass是抽象类,定义了很多抽象方法,要在子类中进行实现。
把不变行为搬到超类,去除子类中的重复代码
1、把组合查询中一些相同的内容提炼出来,建立一个窗体作为父窗体(如下图)
2、添加子窗体
双击‘继承的窗体’---选择开始建立的父窗体
于是子窗体就建好了(如下图)
和父窗体一模一样
仔细看会发现每个控件都有小锁的标志,不可修改,如果要修改只能在父窗体中修改。
3、代码
父窗体:
Public Class frmGroupQueryParentUI '定义组合查询的实体 Protected eGroupQuery As New Entity.GroupQueryInfo Private Sub frmGroupQueryUI_Load(sender As Object, e As EventArgs) Handles Me.Load 'combo框不可编辑 cmbName1.DropDownStyle = 2 cmbName2.DropDownStyle = 2 cmbName3.DropDownStyle = 2 cmbOperator1.DropDownStyle = 2 cmbOperator2.DropDownStyle = 2 cmbOperator3.DropDownStyle = 2 cmbRelation1.DropDownStyle = 2 cmbRelation2.DropDownStyle = 2 '字段名为空 eGroupQuery.cmbName1 = "" eGroupQuery.cmbName2 = "" eGroupQuery.cmbName3 = "" '窗体加载后,后两组控件默认不可用 cmbName2.Enabled = False cmbName3.Enabled = False cmbOperator2.Enabled = False cmbOperator3.Enabled = False txtContent2.Enabled = False txtContent3.Enabled = False '关系2也不可用 cmbRelation2.Enabled = False '选中一个单元格时选中正行 dgv1.SelectionMode = DataGridViewSelectionMode.FullRowSelect End Sub '查询按钮 Private Sub btnQuery_Click(sender As Object, e As EventArgs) Handles btnQuery.Click '判断组合框是否为空 '第一个关系框为空 If cmbRelation1.Text = "" Then If cmbName1.Text = "" Or cmbOperator1.Text = "" Or txtContent1.Text = "" Then MsgBox("第一行查询条件不能为空!", vbOK + vbExclamation, "提示") Exit Sub End If End If '第一个关系框不为空 If cmbRelation1.Text <> "" Then If cmbName1.Text = "" Or cmbOperator1.Text = "" Or txtContent1.Text = "" Or cmbName2.Text = "" Or cmbOperator2.Text = "" Or txtContent2.Text = "" Then MsgBox("第一行和第二行查询条件不能为空,请重新输入!", vbOK + vbExclamation, "提示") Exit Sub End If End If '第二个关系框不为空 If cmbRelation2.Text <> "" Then If cmbName1.Text = "" Or cmbOperator1.Text = "" Or txtContent1.Text = "" Or cmbName2.Text = "" Or cmbOperator2.Text = "" Or txtContent2.Text = "" Or cmbName3.Text = "" Or cmbOperator3.Text = "" Or txtContent3.Text = "" Then MsgBox("第三行查询条件不能为空,请重新输入!", vbOK + vbExclamation, "提示") Exit Sub End If End If '给实体传值 eGroupQuery.dbName = GetdtName() eGroupQuery.cmbName1 = ToEnglish(cmbName1.Text.Trim) eGroupQuery.cmbName2 = ToEnglish(cmbName2.Text.Trim) eGroupQuery.cmbName3 = ToEnglish(cmbName3.Text.Trim) eGroupQuery.cmbOperator1 = cmbOperator1.Text.Trim eGroupQuery.cmbOperator2 = cmbOperator2.Text.Trim eGroupQuery.cmbOperator3 = cmbOperator3.Text.Trim eGroupQuery.txtContent1 = txtContent1.Text.Trim eGroupQuery.txtContent2 = txtContent2.Text.Trim eGroupQuery.txtContent3 = txtContent3.Text.Trim eGroupQuery.cmbRelation1 = ToEnglish(cmbRelation1.Text) eGroupQuery.cmbRelation2 = ToEnglish(cmbRelation2.Text) Dim dt As New DataTable '实例外观层 Dim facadeP As New Facade.GroupQueryParentFacade '调外观方法 dt = facadeP.FGroupQuery(eGroupQuery) '判断是否有记录,没有提示,有在DataGridView中显示 If (dt.Rows.Count = 0) Then MsgBox("没开符合的记录!", vbOK + vbExclamation, "提示") Exit Sub Else Call Todgv(eGroupQuery) End If End Sub '定义转换为数据库中字段的虚方法 Protected Overridable Function ToEnglish(cmbName As String) As String Return "" End Function '定义获得数据库中表的名字 Protected Overridable Function GetdtName() As String Return "" End Function '定义在DataGridView中显示的虚方法 Protected Overridable Sub Todgv(ByVal eGroupQuery As Entity.GroupQueryInfo) End Sub '关系1 combo框选择时判断是否为空,若空,第二第三行空间不可用,否,第二行可用 Private Sub cmbRelation1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cmbRelation1.SelectedIndexChanged If cmbRelation1.Text = "" Then cmbName2.Enabled = False cmbName3.Enabled = False cmbOperator2.Enabled = False cmbOperator3.Enabled = False txtContent2.Enabled = False txtContent3.Enabled = False cmbRelation2.Enabled = False Else cmbName2.Enabled = True cmbOperator2.Enabled = True txtContent2.Enabled = True cmbRelation2.Enabled = True End If End Sub '关系2 combo框选择时判断是否为空,若空,第三行空间不可用,否,第三行可用 Private Sub cmbRelation2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cmbRelation2.SelectedIndexChanged If cmbRelation2.Text = "" Then cmbName3.Enabled = False cmbOperator3.Enabled = False txtContent3.Enabled = False Else cmbName3.Enabled = True cmbOperator3.Enabled = True txtContent3.Enabled = True End If End Sub '清空按钮 Private Sub btnClear_Click(sender As Object, e As EventArgs) Handles btnClear.Click txtContent1.Text = "" txtContent2.Text = "" txtContent3.Text = "" cmbName1.Text = "" cmbName2.Text = "" cmbName3.Text = "" cmbOperator1.Text = "" cmbOperator2.Text = "" cmbOperator3.Text = "" cmbRelation1.Text = "" cmbRelation2.Text = "" dgv1.DataSource = "" End Sub End Class
Public Class frmOperatorWorkLogUI Private Sub frmOperatorWorkLogUI_Load(sender As Object, e As EventArgs) Handles MyBase.Load '给Cmb框赋查询字段 cmbName1.Items.Add("教师") cmbName1.Items.Add("级别") cmbName1.Items.Add("登录日期") cmbName1.Items.Add("登录时间") cmbName1.Items.Add("退出日期") cmbName1.Items.Add("退出时间") cmbName1.Items.Add("机器名") cmbName1.Items.Add("状态") cmbName2.Items.Add("教师") cmbName2.Items.Add("级别") cmbName2.Items.Add("登录日期") cmbName2.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("登录时间") cmbName3.Items.Add("退出日期") cmbName3.Items.Add("退出时间") cmbName3.Items.Add("机器名") cmbName3.Items.Add("状态") End Sub '重载转换数据库中字段的方法 Protected Overrides Function ToEnglish(cmbName As String) As String Select Case cmbName Case "教师" ToEnglish = "userID" Case "级别" ToEnglish = "level" Case "登录日期" ToEnglish = "loginDate" Case "登录时间" ToEnglish = "loginTime" Case "退出日期" ToEnglish = "logoutDate" Case "退出时间" ToEnglish = "logoutTime" Case "机器名" ToEnglish = "computer" Case "状态" ToEnglish = "status" Case "与" ToEnglish = "and" Case "或" ToEnglish = "or" Case Else ToEnglish = "" End Select End Function '重载获得数据库中表的名字的方法 Protected Overrides Function GetdtName() As String Return "T_WorkLog" End Function '重载在DataGridView中显示的方法 Protected Overrides Sub Todgv(ByVal eGroupQuery As Entity.GroupQueryInfo) Dim dt As New DataTable Dim frmGroupParent As New frmGroupQueryParentUI Dim facadeP As New Facade.GroupQueryParentFacade Try dt = facadeP.FGroupQuery(eGroupQuery) '判断是否有记录,有显示,否提示 If dt.Rows.Count = 0 Then MsgBox("没有记录!", vbOK + vbExclamation, "提示") dgv1.DataSource = Nothing dgv1.Refresh() Else dgv1.DataSource = dt dgv1.Columns(0).HeaderText = "教师" dgv1.Columns(1).HeaderText = "级别" dgv1.Columns(2).HeaderText = "登录日期" dgv1.Columns(3).HeaderText = "登录时间" dgv1.Columns(4).HeaderText = "退出日期" dgv1.Columns(5).HeaderText = "退出时间" dgv1.Columns(6).HeaderText = "机器名" dgv1.Columns(7).HeaderText = "状态" dgv1.DefaultCellStyle.Font = New Font("楷体", 16) dgv1.AutoResizeColumns() dgv1.ReadOnly = True End If Catch ex As Exception MsgBox(ex.Message, vbOKOnly, "提示") End Try End Sub End Class
在实践中不断成长,加油!