371
技術社區[雲棲]
重構機房收費係統之 模板方法模式
對於模板方法模式的使用,我後悔自己用晚了,因為我們的機房收費收費係統有很多窗體是幾乎一樣的,如果我們不用模板方法模式,就會大大增加工作量,首先,我們需要重複的創建窗體,其次我們的代碼量也會大大增加,就是複製、粘貼代碼也是一件讓人摒棄的事情,所以推出模板方法模式,用意就在降低代碼重複,減少工作量,通過求同存異的思想來實現。下麵看一下我在組合查詢中用到的模板方法模式:
首先,創建父窗體,父窗體的創建就是普通的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子窗體的代碼很簡單,就是對不同的地方進行了重寫,其他的隻需要繼承父窗體就可以了,至於外觀層、B層、D層與其他窗體都是一樣的,在這裏就不一一列出了。
設計模式學了很多種模式,可是真正去想的時候,也隻是知道有這麼個模式,至於怎麼用,不知道,隻有在敲機房的時候,使勁的加,才能體會到它的好處與不足,讓知識活了起來!
最後更新:2017-04-03 08:26:19