机房收费系统之模版方法使用

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

    1.使用意图

     我们经常会遇到这样的问题:知道一个算法需要的步骤和顺序,但是每个算法的具体实现不同,比如在机房收费系统中,组合查询有四个窗体类,每个窗体类的算法结构相同,具体实现不同,此时我们可以使用模版方法。

    模版方法模式 把我们不知道具体实现的步骤封装成抽象方法,提供一个按正确顺序调用他们的具体方法,构成一个抽象基类,子类继承抽象基类实现各个步骤的抽象方法,工作流程由抽象基类控制。把实现推迟到子类中,通过继承来达到对象的复用,同时遵守开闭原则。

  2.例子:

   不使用模版方法做组合查询窗体时需要画4个组合查询窗体的界面,界面相同,同时需要添加相同的控件和代码,比如:查询操作符、组合关系、验证代码等;但是,用模版方法我们仅仅需要增加一个模版窗体,将控件和相同的代码放入模版窗体,让其他四个窗体继承模版窗体,重定义某一方法即可。

下面看代码:

举例:机房收费系统组合查询

模版窗体代码:

Public MustInheritClass frmTemplate
#Region"查询方法"
    ''' <summary>
    ''' 查询方法
    ''' </summary>
    ''' <paramname="sender"></param>
    ''' <paramname="e"></param>
    ''' <remarks></remarks>
    Private Sub btnQuery_Click(sender AsObject, e As EventArgs) Handles btnQuery.Click
        ' "基础判断代码"
        ‘略
        '限制非法字符输入
        ‘略
        '实体传参
        ‘略
        '绑定数据
        Try
            dt = GetMethod(comqueryen)
        Catch ex As Exception
            MsgBox(ex.Message)
        Finally
            DataGridView1.DataSource = dt
        End Try
    End Sub
#End Region
    '调用不同的方法
    Public MustOverride FunctionGetMethod(comqueryen) As DataTable
End Class


子类窗体代码:

Public ClassfrmStuInfo : Inherits UI.frmTemplate
#Region"重写方法"
    ''' <summary>
    ''' 重新抽象类中的获取方法
    ''' </summary>
    ''' <paramname="comqueryen">组合查询实体</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides FunctionGetMethod(comqueryen) As DataTable
        Dim dt As New DataTable
        Dim Fstudent As New Facade.FStudent
        dt = Fstudent.StudentInfo(comqueryen)
        Return dt
    End Function
#End Region

   

同时我们比较一下Designer里的代码:

不用模版方法时,四个窗体每个窗体的Designer代码:

 

'Windows 窗体设计器所必需的
    Private components AsSystem.ComponentModel.IContainer
    '注意: 以下过程是 Windows 窗体设计器所必需的
    '可以使用 Windows 窗体设计器修改它。
    '不要使用代码编辑器修改它。
   <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
        Me.GroupBox1 = NewSystem.Windows.Forms.GroupBox()
        Me.DataGridView1 = NewSystem.Windows.Forms.DataGridView()
        Me.btnCancel = NewSystem.Windows.Forms.Button()
        Me.btnQuery = NewSystem.Windows.Forms.Button()
        Me.cboRelative2 = NewSystem.Windows.Forms.ComboBox()
        Me.cboRelative1 = NewSystem.Windows.Forms.ComboBox()
        Me.txtCondition3 = NewSystem.Windows.Forms.TextBox()
        Me.txtCondition2 = NewSystem.Windows.Forms.TextBox()
        Me.txtCondition1 = NewSystem.Windows.Forms.TextBox()
        Me.cboOperate3 = NewSystem.Windows.Forms.ComboBox()
        Me.cboOperate2 = NewSystem.Windows.Forms.ComboBox()
        Me.cboOperate1 = NewSystem.Windows.Forms.ComboBox()
        Me.cboFile3 = NewSystem.Windows.Forms.ComboBox()
        Me.cboFile2 = NewSystem.Windows.Forms.ComboBox()
        Me.cboFile1 = NewSystem.Windows.Forms.ComboBox()
        Me.lblRelative = NewSystem.Windows.Forms.Label()
        Me.lblCondition = NewSystem.Windows.Forms.Label()
        Me.lblOperate = NewSystem.Windows.Forms.Label()
        Me.lblFile = NewSystem.Windows.Forms.Label()
        Me.btnModify = NewSystem.Windows.Forms.Button()
        Me.GroupBox1.SuspendLayout()
        CType(Me.DataGridView1,System.ComponentModel.ISupportInitialize).BeginInit()
        Me.SuspendLayout()
        'frmTemplate
        Me.AutoScaleDimensions = NewSystem.Drawing.SizeF(6.0!, 12.0!)
        Me.AutoScaleMode =System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = NewSystem.Drawing.Size(855, 442)
        Me.Controls.Add(Me.GroupBox1)
        Me.Name = "frmTemplate"
        Me.Text = "组合查询"
        Me.GroupBox1.ResumeLayout(False)
        Me.GroupBox1.PerformLayout()
        CType(Me.DataGridView1,System.ComponentModel.ISupportInitialize).EndInit()
        Me.ResumeLayout(False)
    End Sub
    Friend WithEvents GroupBox1 AsSystem.Windows.Forms.GroupBox
    Friend WithEvents DataGridView1 AsSystem.Windows.Forms.DataGridView
    Friend WithEvents btnCancel AsSystem.Windows.Forms.Button
    Friend WithEvents btnQuery AsSystem.Windows.Forms.Button
    Friend WithEvents cboRelative2 AsSystem.Windows.Forms.ComboBox
    Friend WithEvents cboRelative1 AsSystem.Windows.Forms.ComboBox
    Friend WithEvents txtCondition3 AsSystem.Windows.Forms.TextBox
    Friend WithEvents txtCondition2 AsSystem.Windows.Forms.TextBox
    Friend WithEvents txtCondition1 AsSystem.Windows.Forms.TextBox
    Friend WithEvents cboOperate3 AsSystem.Windows.Forms.ComboBox
    Friend WithEvents cboOperate2 AsSystem.Windows.Forms.ComboBox
    Friend WithEvents cboOperate1 AsSystem.Windows.Forms.ComboBox
    Friend WithEvents cboFile3 AsSystem.Windows.Forms.ComboBox
    Friend WithEvents cboFile2 AsSystem.Windows.Forms.ComboBox
    Friend WithEvents cboFile1 AsSystem.Windows.Forms.ComboBox
    Friend WithEvents lblRelative AsSystem.Windows.Forms.Label
    Friend WithEvents lblCondition AsSystem.Windows.Forms.Label
    Friend WithEvents lblOperate AsSystem.Windows.Forms.Label
    Friend WithEvents lblFile AsSystem.Windows.Forms.Label
    Friend WithEvents btnModify AsSystem.Windows.Forms.Button


   用上模版方法后,仅模版方法里的代码如上,其他子类窗体的Designer代码如下:

'Windows 窗体设计器所必需的
    Private components AsSystem.ComponentModel.IContainer
 
    '注意: 以下过程是 Windows 窗体设计器所必需的
    '可以使用 Windows 窗体设计器修改它。
    '不要使用代码编辑器修改它。
   <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
        Me.SuspendLayout()
        '
        'frmStuInfo1
        '
        Me.AutoScaleDimensions = NewSystem.Drawing.SizeF(6.0!, 12.0!)
        Me.AutoScaleMode =System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = NewSystem.Drawing.Size(871, 481)
        Me.Name = "frmStuInfo"
        Me.Text = "学生信息查询"
        Me.ResumeLayout(False)
    End Sub 

    差异是巨大的,通过使用模版方法,我们达到了对象的复用,减少了错误概论,修改起来也很方便。

      当然,各个设计模式都不是孤立存在的,各模式之间都有联系。模版中的重定义方法和工厂方法类似,将实现延迟到子类中;模版和策略方法可以同时使用,例如在机房收费系统中,计算临时用户收费和固定用户收费的步骤是相同的,不同的是收费单价,所以我们可以使用模版方法将具体的方法重定义,将两个方法用策略模式封装。

   对模版方法的一些理解,不足指出敬请指正!

你可能感兴趣的:(机房收费系统之模版方法使用)