设计模式虽然学了一遍,但也仅限于纸上谈兵,在机房重构中还是不知道如何去用,而且感觉刻意去套模式还麻烦,但是使用模板方法的好处确是实实在在,显而易见的啊,既大大减少了代码量还省去了绘制窗体界面的麻烦,给一个大大的赞~~
模板方法
先是定义一个顶级算法的骨架,将代码提炼,而将一些步骤延迟到子类;而子类可重定义算法的某些步骤,实现父类所定义的抽象方法。
组合查询
1、建立模板父窗体
'实例化组合查询的实体 Protected GroupInquire As New Model.GroupInquireInfo Private Sub frmGroupParent_Load(sender As Object, e As EventArgs) Handles MyBase.Load '将参数传递给实体,赋初值 '字段名 GroupInquire.CmbName1 = "" GroupInquire.CmbName2 = "" GroupInquire.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 = False CmbName3.Enabled = False CmbMark2.Enabled = False CmbMark3.Enabled = False CmbRelation2.Enabled = False txtContent2.Enabled = False txtContent3.Enabled = False Dim i As Integer For i = 0 To dgv.Columns.Count - 1 dgv.Columns(i).Width = DataGridViewAutoSizeColumnMode.AllCells Next End Sub '查询 Private Sub btnQuery_Click(sender As Object, e As EventArgs) Handles btnQuery.Click If CmbRelation1.Text = "" Then If CmbName1.Text = "" Or CmbMark1.Text = "" Or txtContent1.Text = "" Then MsgBox("第一行查询条件不能为空,请完善", , "提示") Exit Sub End If End If If CmbRelation1.Text <> "" Then If CmbName1.Text = "" Or CmbMark1.Text = "" Or txtContent1.Text = "" Or CmbName2.Text = "" Or CmbMark2.Text = "" Or txtContent2.Text = "" Then MsgBox("所输入的查询条件不能为空,请完善", , "提示") Exit Sub End If End If If CmbRelation2.Text <> "" Then If 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 = "" Then MsgBox("所输入的查询条件不能为空,请完善", , "提示") Exit Sub End If End If '将参数传给实体 GroupInquire.DbName = GetdbName() GroupInquire.CmbName1 = GetEnglish(CmbName1.Text) GroupInquire.CmbName2 = GetEnglish(CmbName2.Text) GroupInquire.CmbName3 = GetEnglish(CmbName3.Text) GroupInquire.CmbMark1 = CmbMark1.Text.Trim GroupInquire.CmbMark2 = CmbMark2.Text.Trim GroupInquire.CmbMark3 = CmbMark3.Text.Trim GroupInquire.TxtContent1 = txtContent1.Text.Trim GroupInquire.TxtContent2 = txtContent2.Text.Trim GroupInquire.TxtContent3 = txtContent3.Text.Trim GroupInquire.CmbRelation1 = GetEnglish(CmbRelation1.Text) GroupInquire.CmbRelation2 = GetEnglish(CmbRelation2.Text) Dim dt As New DataTable Dim Generalfacade As New Facade.GeneralFacade '实例化外观层 dt = Generalfacade.FGroupCheck(GroupInquire) If (dt.Rows.Count = 0) Then MsgBox("没有符合条件的记录", , "提示") Exit Sub Else Call Todgv(GroupInquire) '把表显示到datagridview中 End If End Sub '模板方法,定义虚函数GetEnglish,查询字段转化为数据库字段 Public Overridable Function GetEnglish(cmbName As String) As String Return "" End Function '获得数据库表名 Protected Overridable Function GetdbName() As String Return "" End Function '把表显示到datagridview中 Protected Overridable Sub Todgv(ByVal comQueryEntity As GroupInquireInfo) End Sub '第一个组合关系是否为空 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 ' 第二个组合关系是否为空 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 Sub2、建立子窗体
如下图建立子窗体,然后选择要继承的父窗体,再然后神奇的事情便发生了:子窗体竟然和父窗体一模一样,一下子就省了不少时间~同样,在子窗体里重写类和方法就OK了,只需在U层这一层写就行。
子窗体代码如下:
Private Sub frmGroupStuInfo_Load(sender As Object, e As EventArgs) Handles MyBase.Load '赋初值 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("班级") CmbName3.Items.Add("卡号") CmbName3.Items.Add("学号") CmbName3.Items.Add("姓名") CmbName3.Items.Add("性别") CmbName3.Items.Add("专业") CmbName3.Items.Add("年级") CmbName3.Items.Add("班级") End Sub '把加载的汉字转换成数据库的字段 Public Overrides Function GetEnglish(cmbName As String) As String Select Case cmbName Case "卡号" GetEnglish = "CardNo" Case "学号" GetEnglish = "StudentNo" Case "姓名" GetEnglish = "StudentName" Case "性别" GetEnglish = "Sex" Case "专业" GetEnglish = "Department" Case "年级" GetEnglish = "Grade" Case "班级" GetEnglish = "StudentClass" Case "与" GetEnglish = "and" Case "或" GetEnglish = "or" Case Else GetEnglish = "" End Select End Function '传数据库表名 Protected Overrides Function GetdbName() As String Return "Student_info" End Function '查询并把数据显示到datagridview中 Protected Overrides Sub Todgv(ByVal comQueryEntity As GroupInquireInfo) Dim table As New DataTable Dim frmGroupParent As New frmGroupParent Dim GeneralFacade As New Facade.GeneralFacade Try table = GeneralFacade.FGroupCheck(comQueryEntity) If table.Rows.Count = 0 Then table.Clear() dgv.DataSource = Nothing dgv.Refresh() Else dgv.DataSource = table dgv.Columns(0).Visible = False dgv.Columns(0).HeaderText = "卡号" dgv.Columns(1).HeaderText = "学号" dgv.Columns(2).HeaderText = "姓名" dgv.Columns(3).HeaderText = "专业" dgv.Columns(4).HeaderText = "性别" dgv.Columns(5).HeaderText = "年级" dgv.Columns(6).HeaderText = "班级" dgv.Columns(7).HeaderText = "金额" dgv.Columns(8).HeaderText = "备注" dgv.Columns(9).HeaderText = "是否结账" dgv.Columns(10).HeaderText = "状态" dgv.Columns(11).HeaderText = "用户类型" dgv.Columns(12).HeaderText = "注册日期" dgv.Columns(13).HeaderText = "注册时间" End If Catch ex As Exception MsgBox(ex.Message, vbOKOnly, "提示") End Try End Sub3、DAL层数据库查询
Public Function IGroupCheck(Groupcheck As Model.GroupInquireInfo) As DataTable Implements IGroupQuery.IGroupCheck Dim sql As String Dim table As DataTable sql = "select * from " & Groupcheck.DbName & " where " If Trim(Groupcheck.CmbRelation1) = "" Then '有一组查询条件 sql = sql & Groupcheck.CmbName1 & Groupcheck.CmbMark1 & "'" & Groupcheck.TxtContent1 & "'" Else If Trim(Groupcheck.CmbRelation2) = "" Then '有两组查询条件 sql = sql & Groupcheck.CmbName1 & Groupcheck.CmbMark1 & "'" & Groupcheck.TxtContent1 & "'" & Groupcheck.CmbRelation1 & " " & Groupcheck.CmbName2 & Groupcheck.CmbMark2 & "'" & Groupcheck.TxtContent2 & "'" Else sql = sql & Groupcheck.CmbName1 & Groupcheck.CmbMark1 & "'" & Groupcheck.TxtContent1 & "'" & Groupcheck.CmbRelation1 & " " & Groupcheck.CmbName2 & Groupcheck.CmbMark2 & "'" & Groupcheck.TxtContent2 & "'" & Groupcheck.CmbRelation2 & " " & Groupcheck.CmbName3 & Groupcheck.CmbMark3 & "'" & Groupcheck.TxtContent3 & "'" End If End If '模板的无参查询 table = sqlHelper.ExeSelectNo(sql, CommandType.Text) Return table End Function小结
组合查询、一般查询都有好多类似功能的窗体,那么使用模板方法无疑会给我们带来很大的方便,它通过把不变行为搬移到超类,去除子类中的重复代码体现出了其优势。因此,对于设计模式,还是要韩信点兵——多多益善。