重构机房收费系统之 模板方法模式

对于模板方法模式的使用,我懊悔自己用晚了,由于我们的机房收费收费系统有非常多窗口是差点儿一样的,假设我们不用模板方法模式,就会大大添加工作量,首先,我们须要反复的创建窗口,其次我们的代码量也会大大添加,就是复制、粘贴代码也是一件让人摒弃的事情,所以推出模板方法模式,用意就在降低代码反复,降低工作量,通过求同存异的思想来实现。以下看一下我在组合查询中用到的模板方法模式:

首先,创建父窗口,父窗口的创建就是普通的winform,我们知道组合查询这块儿一共同拥有四个窗口是大同小异的:学生上机状态查看、上机信息统计、学生基本信息维护、操作员工作记录,他们的窗口(包含控件)是一致的,除字段名和要查询的内容不一样,其余都一样,所以要用到重写,在每一个子窗口中依据本窗口的须要而有所不同:以下看一下父窗口的代码:

Imports Entity
Imports Facade
Public Class frnMulSelection
    Protected enMulSelection As New MulSelectionEntity
    ''' <summary>
    ''' 查询
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub btnQuery_Click(sender As Object, e As EventArgs) Handles btnQuery.Click
        Try
            '假设第一个连接条件为空
            If cboConnection1.Text.Trim = "" Then
                Dim arrayControl() As Control
                ReDim Preserve arrayControl(2)

                arrayControl(0) = cboFields1
                arrayControl(1) = cboOperator1
                arrayControl(2) = txtContent1
                '推断第一行是否为空
                If IsSomeEmptyText(arrayControl) = True Then
                    Exit Sub
                End If
                SelectData()
            Else
                If cboConnection2.Text.Trim = "" Then
                    Dim arrayControl() As Control
                    ReDim Preserve arrayControl(6)

                    arrayControl(0) = cboFields1
                    arrayControl(1) = cboOperator1
                    arrayControl(2) = txtContent1
                    arrayControl(3) = cboConnection1
                    arrayControl(4) = cboFields2
                    arrayControl(5) = cboOperator2
                    arrayControl(6) = txtContent2
                    '推断第一行是否为空
                    If IsSomeEmptyText(arrayControl) = False Then
                        Exit Sub
                    End If
                Else
                    '假设关系1和2都不为空,推断控件内容是否为空
                    If IsAllEmptyText(Me) = False Then
                        Exit Sub
                    End If
                End If
            End If
        Catch ex As Exception
            MsgBox(ex.Message, MsgBoxStyle.Exclamation, "提示")
        End Try
    End Sub
    ''' <summary>
    ''' 字段名
    ''' </summary>
    ''' <param name="getFields"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>

    Public Overridable Function sqlFields(ByVal getFields As String) As String
        Return ""
    End Function

    ''' <summary>
    ''' 获取表名
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overridable Function GetTable() As String
        Return ""
    End Function

    ''' <summary>
    ''' 拼接字符串
    ''' </summary>
    ''' <param name="frm"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Query(frm As frnMulSelection) As String
        Dim strConnection As String '拼接字符串
        '假设第一个链接条件为空
        If frm.cboConnection1.Text = "" Then
            strConnection = " " & sqlFields(frm.cboFields1.Text) & frm.cboOperator1.Text & " '" & frm.txtContent1.Text & "'"
        Else
            '假设第一个不为空,第二个为空
            If Me.cboConnection2.Text = "" Then
                strConnection = " " & sqlFields(Me.cboFields1.Text) & Me.cboOperator1.Text & " '" & Me.txtContent1.Text & "'" &
                    sqlFields(Me.cboConnection1.Text) & " " & sqlFields(Me.cboFields2.Text) & Me.cboOperator2.Text & "'" & Me.txtContent2.Text & "'"
            Else
                '假设两个链接条件都不为空
                strConnection = " " & sqlFields(Me.cboFields1.Text) & Me.cboOperator1.Text & " '" & Me.txtContent1.Text & "'" &
                    sqlFields(Me.cboConnection1.Text) & " " & sqlFields(Me.cboFields2.Text) & Me.cboOperator2.Text & "'" & Me.txtContent2.Text & "'" &
                    sqlFields(Me.cboConnection2.Text) & " " & sqlFields(Me.cboFields3.Text) & Me.cboOperator3.Text & "'" & Me.txtContent3.Text & "'"
            End If
        End If
        Return strConnection
    End Function
    ''' <summary>
    ''' 运行查询的关键函数
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Protected Overridable Function SelectData()
        Return ""
    End Function

    ''' <summary>
    ''' 退出
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
        Me.Dispose()
    End Sub

    Private Sub frnMulSelection_Load(sender As Object, e As EventArgs) Handles Me.Load
        '将每一个表共同的操作符提取出来
        btnMofify.Visible = False
        cboOperator1.Items.Add("=")
        cboOperator1.Items.Add("<")
        cboOperator1.Items.Add(">")
        cboOperator1.Items.Add("<>")

        cboOperator2.Items.Add("=")
        cboOperator2.Items.Add("<")
        cboOperator2.Items.Add(">")
        cboOperator2.Items.Add("<>")

        cboOperator3.Items.Add("=")
        cboOperator3.Items.Add("<")
        cboOperator3.Items.Add(">")
        cboOperator3.Items.Add("<>")

        'cboConnection1.SelectedIndex = 1
        cboConnection1.Items.Add("")
        cboConnection1.Items.Add("与")
        cboConnection1.Items.Add("或")
        'cboConnection2.SelectedIndex = 1
        cboConnection2.Items.Add("")
        cboConnection2.Items.Add("与")
        cboConnection2.Items.Add("或")
        '在父窗口中填充选项
        enMulSelection.Fields1 = "1"
        enMulSelection.Fields2 = "1"
        enMulSelection.Fields3 = "1"
        enMulSelection.Operator1 = "="
        enMulSelection.Operator2 = "="
        enMulSelection.Operator3 = "="
        enMulSelection.Content1 = "1"
        enMulSelection.Content2 = "1"
        enMulSelection.Content3 = "1"
        enMulSelection.Connection1 = "and"
        enMulSelection.Connection2 = "and"
        '在一開始的时候,仅仅同意第一个条件行可用,仅仅有选择了连接关系后,其它以下的条件行在能够用
        cboFields2.Enabled = False
        cboOperator2.Enabled = False
        txtContent2.Enabled = False
        cboConnection2.Enabled = False
        cboFields3.Enabled = False
        cboOperator3.Enabled = False
        txtContent3.Enabled = False

    End Sub
    ''' <summary>
    ''' 假设选择了第一个连接调节,则第二个条件行也能够写入
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub cboConnection1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboConnection1.SelectedIndexChanged
        cboFields2.Enabled = True
        cboOperator2.Enabled = True
        txtContent2.Enabled = True
        cboConnection2.Enabled = True
    End Sub
    ''' <summary>
    ''' 同上
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub cboConnection2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboConnection2.SelectedIndexChanged
        cboFields3.Enabled = True
        cboOperator3.Enabled = True
        txtContent3.Enabled = True

    End Sub
    ''' <summary>
    '''用于学生信息维护中的改动学生信息时选中某行改动,是虚函数
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Public Overridable Sub DataGridView1_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellClick

    End Sub
End Class

子窗口是这样继承的:

点击“加入”后,选择要继承的父窗口:

以下是子窗口的代码:

Imports Facade '导入外观
Imports Entity '导入实体
Public Class frmMulWorkLog
    Private Sub frmMulWorkLog_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        cboFields1.Items.Add("教师")
        cboFields1.Items.Add("注冊日期")
        cboFields1.Items.Add("注冊时间")
        cboFields1.Items.Add("注销日期")
        cboFields1.Items.Add("注销时间")
        cboFields1.Items.Add("机器号")

        cboFields2.Items.Add("教师")
        cboFields2.Items.Add("注冊日期")
        cboFields2.Items.Add("注冊时间")
        cboFields2.Items.Add("注销日期")
        cboFields2.Items.Add("注销时间")
        cboFields2.Items.Add("机器号")

        cboFields3.Items.Add("教师")
        cboFields3.Items.Add("注冊日期")
        cboFields3.Items.Add("注冊时间")
        cboFields3.Items.Add("注销日期")
        cboFields3.Items.Add("注销时间")
        cboFields3.Items.Add("机器号")

    End Sub
    Protected Overrides Function SelectData() As Object

        Dim facWorkLog As New WorkLogFacade
        Dim dtWorkLog As New DataTable
        Dim frmmulworklog As New frmMulWorkLog

        Dim strConnection As String
        strConnection = frmmulworklog.Query(Me) '此处用到了多态,把子类传给父类,重写父类的方法。

        Try
            dtWorkLog = facWorkLog.SelectMulWork(strConnection)
            If dtWorkLog.Rows.Count <= 0 Then
                dtWorkLog.Clear() '清空datatable中上次的记录
                DataGridView1.DataSource = Nothing '使表中的数据为空
                DataGridView1.Refresh() '又一次绘制表
            Else
                DataGridView1.DataSource = dtWorkLog
                DataGridView1.Columns(0).Visible = False
                DataGridView1.Columns(0).HeaderText = "序列号"
                DataGridView1.Columns(1).HeaderText = "教师"
                DataGridView1.Columns(2).Visible = False
                DataGridView1.Columns(2).HeaderText = "用户级别"
                DataGridView1.Columns(3).HeaderText = "注冊日期"
                DataGridView1.Columns(4).HeaderText = "注冊时间"
                DataGridView1.Columns(5).HeaderText = "注销日期"
                DataGridView1.Columns(6).HeaderText = "注销时间"
                DataGridView1.Columns(7).HeaderText = "机器号"
            End If

        Catch ex As Exception
            MsgBox(ex.Message, MsgBoxStyle.Exclamation, "提示")
        End Try

    End Function
    Public Overrides Function sqlFields(getFields As String) As String

        Select Case getFields
            Case "序列号"
                Return "serious"
            Case "教师"
                Return "UserName"
            Case "用户级别"
                Return "UserLevel"
            Case "注冊日期"
                Return "LogOnDate"
            Case "注冊时间"
                Return "LogOnTime"
            Case "注销日期"
                Return "LogOffDate"
            Case "注销时间"
                Return "LogOffTime"
            Case "机器号"
                Return "机器号"
            Case "或"
                Return "Or"
            Case "与"
                Return "And"
            Case Else
                Return ""
        End Select

    End Function
    Public Overrides Function GetTable() As String
        enMulSelection.Table = "T_WorkLog"
        Return "T_WorkLog"
    End Function
End Class

子窗口的代码非常easy,就是对不同的地方进行了重写,其它的仅仅须要继承父窗口就能够了,至于外观层、B层、D层与其它窗口都是一样的,在这里就不一一列出了。

设计模式学了非常多种模式,但是真正去想的时候,也仅仅是知道有这么个模式,至于怎么用,不知道,仅仅有在敲机房的时候,使劲的加,才干体会到它的优点与不足,让知识活了起来!

重构机房收费系统之 模板方法模式

时间: 2024-10-29 11:53:53

重构机房收费系统之 模板方法模式的相关文章

重构机房收费系统总结1之配置文件+反射+抽象工厂

在重构机房收费系统之前就一直听说这次重构要用反射+配置文件.深远的作用不知道,但是在这次重构用到,目的还是挺明确的:就是为了更换数据时方便,遵循开放-封闭原则,解决了可维护和可扩展的问题. 下面就以机房收费系统登录为例来看看配置文件+反射的用法.机房收费系统登录用到的数据库表是User_info表(用户表).我利用的是三层思想,先看一下我的整体架构! 下面看看配置文件+反射+抽象工厂在登录时访问数据库User表时的用法. 1.先进行配置文件操作 步骤:(1)在VS资源管理器的新建项目UI中,会有

重构机房收费系统前夕

VB版的机房收费系统完了之后,到c#,几乎没怎么写代码了,重新敲起那段回忆,还依稀能看到以前的影子,但是很多理论的知识感觉都已模模糊糊. 设计模式是面向对象编程的大牛们总结出的很多经典的面向对象程序设计的套路,面向过程就像是迷途的孩子,走的路越多,越难以找到顺着道找到回家的路,而面向对象就像是有了家的孩子,走到哪都能找到回家的路.呵呵,当然是有家的孩子好了. 学了UML之后,我们知道施工需要图纸,做一个项目,需要建模,学了设计模式之后我们知道程序的设计要考虑的不仅仅是写代码的时候方便,而更多的是

重构机房收费系统—浅谈三层

重构机房基本完成了,期间三层重构完了,推翻之后,再重构七层(外观和工厂),再重构,来来回回用了一个月........ 重构机房从画图画到一半就废弃了,因为对三层不熟,之后,做完了,才敢重新拾起来画.画图先从包图开始,宏观上有个了解: (一)重构机房包图: 先前画包图的时候,跟师傅交流,结果被一个师姐给笑话了,因为我认为:它们各个层之间都是双向箭头的,后来才知道,箭头表示调用关系,B层只能被U层或外观调用,B层不能调用U层,所以不存在双向箭头,大家注意. 在我这次重构中是严格按照上面的图中来的.

重构机房收费系统——数据库设计

曾记得,第一次编写机房收费系统的文档模板,整整有12个文档需要编写,仅仅花了两三天的时间就让师傅验收,完结项目,就这样囫囵吞枣的文档编写完成了. 要知道:欠下的账,终究是要还的.现在到了机房收费系统个人版重构阶段, (1)进行数据抽象,设计局部概念模型: (2)将局部概念模型综合成全局概念模型 (3)就可以按要求绘制机房收费系统数据库概念设计模型--ER关系图. 可以说,之前的数据库的概念设计给我奠定了一丢丢的设计基础,外加<数据库系统原理>中的三范式定理,本着求知好学.虚心请教的理念,于是乎

重构机房收费系统你要用的——异常处理和抛出异常(try catch finally)——(vb.net)

你能保证你的程序不会出问题吗? 不能 当你的程序执行到某个地方发生了你不想要的结果.你是否想让它一错再错? 不想 你是否想让你的程序占着茅坑不拉屎? 不想 你是否想知道你的程序出错的原因? 想 看了了这4个问题之后.假设你的回答和我的一致,那么请看下文 trycatch finally的使用方法: try '你想要写的程序 catch '捕获你想写的程序里面全部发生的异常 finally '不管发生还是不发生异常,你都想运行的代码 演示样例: Dim Update_Info As String 

vb.net版机房收费系统重构的成长历程(功能实现篇)

重构机房收费系统,功能是不变的,需求是不变的,系统背后的代码,架构发生了改变.做过vb6.0版的系统 后,利用VS的VB.NET平台, 通过调整程序架构,加入了设计模式,改善软件的质量.性能,提高软件的扩展性和维护性.相比旧版系统,新版系统主要亮点有: 亮点一:代码分层管理,清晰明了 亮点二:加入工厂和接口,代码复用较多,减少了重复或相似的代码. 亮点三:用到了存储过程.一方面减少了代码量,另一方面也相当于是一个事务的执行.比如注册或者结账需要同 时操作多张表,这几个表必须同时被操作成功后才可以

vb.net版机房收费系统重构

机房收费系统重构版终于正式开工了! 前几天,刚刚看完三层的视频,在视频中详细的讲解了一个登录功能.天真的我,当时以为三层结构是那么的简单,所以我草草地做完总结之后,就很快就开始机房收费系统的重构了.可是谁想到,当我一打开编程软件,就让我"碰了一鼻子的灰"!首先是不知道vs 怎么用,其次就是看三层的时候,登录的实例使用C#写的,而这次我们需要用VB.NET写,所以对于其中的语法是知之甚少.虽然,前段时间我看了一遍台湾讲师--曹祖胜的<VB.NET 视频>,但是他讲的几乎都是一

#【数据库】机房收费系统数据库设计

前言 前一段时间要参加自考,要考<数据库原理>,在其中也更加了解了好多数据库的问题.比如,如何创建一个好的数据库,怎么创建数据库. 图一 数据库创建框架 现在开始机房的重构,以前用的是师哥师姐设计的数据库,现在发现自己也可以设计出来了,所以,按这步骤来自己设计一个机房收费系统的数据库. 一.规划 由于机房收费系统是第二遍做的,所以在总体规划阶段很容易看出系统在技术.经济.效益.法律是可行的:目标就是要更好的搭配应用程序合理运行. 二.需求分析 这一阶段是计算机人员(系统分析员)和用户双方共同收

VB.NET机房收费 &amp;amp; 抽象工厂模式

学习设计模式的时候,提到了一个专门訪问数据库的模式-抽象工厂模式,记得当时举样例理解的时候并未设计到数据库,仅仅是大概了了解了一下,如今对于机房收费系统涉及到了数据库的管理,借此机会好好学习一下.用常常说的一句经典的话语则是:欠的债总是要还的,这句话同一时候也警告自己对于学习要一心一意,切勿粗心大意.       欢迎訪问自己对于工厂三姐妹的理解 对照能够知道,对于抽象工厂模式的初步理解,则是 重构机房收费系统,对于数据库的选择方法则是在D层建立一个单独的类,来连接字符串. 而在此使用工厂层,其