標籤:職責鏈模式 機房重構下機 重構 鏈表
前幾天一直在講設計模式,在和師哥師姐的討論過程中,發現能在機房收費個人重構版中用到好幾個設計模式,首先來討論討論職責鏈模式:
首先當看見這個模式的第一眼就覺得這是一個很簡單的模式,可是當使用起來真的得考慮許多,首先要明白什麼是鏈?鏈是一系列節點的集合,可以靈活拆分再重組。這也是與 鏈表不同的地方,使用者可以去訪問節點中的任何一點作為開始節點。
定義: 使多個對象都有機會處理請求,從而避免請求的寄件者和接受者之間的耦合關係。將這個對象連成一條鏈,並沿著這條鏈傳遞該請求,直到有一個對象處理他為止。舉例:
現在正在敲個人重構版機房收費系統,在下機的過程中,我們需要和基本資料的設定聯絡起來,即上機時間是分為三段來考慮的,準備時間,至少上機時間,單位遞增時間,在判斷處理的時候他則是一次來進行的,這不正與職責鏈模式不謀而合了嗎?參照職責鏈中漲工資的小故事,我們可以把分成三個類,準備時間,至少上機時間和單位時間
看相關代碼:
首先得需要一個抽象類別,處理請求的一個介面:
'BL_TimeHandler,抽象類別,定義一個處理請求的介面Public MustInherit Class BL_TimeHandler Protected calaulate As BL_TimeHandler Public Sub Setcalaulate(ByVal calaulate As BL_TimeHandler) '設定繼承者 Me.calaulate = calaulate End Sub '處理請求的抽象方法 Public MustOverride Function HandleTime(ByVal time As Integer) As IntegerEnd Class
然後就是三個子類對於父類的繼承:
'BL_PrepareTimeHandler,準備時間處理類,繼承BL_TimeHandlerPublic Class BL_PrepareTimeHandler : Inherits BL_TimeHandler Dim preparetime As Integer '建構函式,利用泛型集合傳入準備時間的值 Public Sub New(ByVal EnBasicdata As IList(Of Entity.BasicDataEntity)) Me.preparetime = CInt(EnBasicdata(0).prepareTime) '返回運算式 End Sub Public Overrides Function HandleTime(time As Integer) As Integer If time <= preparetime Then '如果上機時間<準備時間,返回0 Return 0 Else Return calaulate.HandleTime(time) '轉到下一位繼承者 End If End FunctionEnd Class
'BL_unitTimeHandler,單位時間處理類Public Class BL_unitTimeHandler : Inherits BL_TimeHandler Private unittime As Integer '建構函式,傳入遞增時間 Public Sub New(ByVal enBasicdata As IList(Of Entity.BasicDataEntity)) Me.unittime = CInt(enBasicdata(0).unitTime) End Sub '大於至少時間,返回實際消費時間 Public Overrides Function HandleTime(time As Integer) As Integer Return Math.Abs(Int(-time / unittime)) * unittime End Function
'BL_LeastTimeHandler, 至少上機時間類Public Class BL_LeastTimeHandler : Inherits BL_TimeHandler Private LeastTime As Integer '建構函式,傳入最少上機時間的值 Public Sub New(ByVal enBasicdata As IList(Of Entity.BasicDataEntity)) Me.LeastTime = CInt(enBasicdata(0).leastTime) End Sub Public Overrides Function HandleTime(time As Integer) As Integer If time <= LeastTime Then Return LeastTime Else Return calaulate.HandleTime(time) End If End FunctionEnd Class
至此職責鏈模式就到此結束了,為了便於調用,可以增加一個介面,方便調用,這樣就只需要傳入兩個參數就可了。
Public Class BL_OnlineTimeCount Public Function CostTime(ByVal enbasicdata As IList(Of Entity.BasicDataEntity), enLineInfo As Entity.LineEntity) As Integer '執行個體化類,通過建構函式,傳遞函數 Dim bPrepareTime As New BL_PrepareTimeHandler(enbasicdata) Dim bLeastTime As New BL_LeastTimeHandler(enbasicdata) Dim bStepTime As New BL_unitTimeHandler(enbasicdata) bPrepareTime.Setcalaulate(bLeastTime) '設定職責鏈繼承者 bLeastTime.Setcalaulate(bStepTime) Dim time As Integer '計算上下機時間差 time = DateDiff("n", enLineInfo.Ontime, enLineInfo.Offtime) + DateDiff("n", enLineInfo.Ondate, enLineInfo.Offdate) Return bPrepareTime.HandleTime(time) '職責鏈處理,返回上機時間 End FunctionEnd Class
在U層中的調用代碼:
Dim enline As New Entity.LineEntity With enline .Ondate = lineRe(0).Ondate .Ontime = lineRe(0).Ontime .Offdate = CStr(Format(Now(), "yyyy-MM-dd")) .Offtime = CStr(Format(Now(), "HH:mm:ss")) End With Dim basicdataList As IList(Of Entity.BasicDataEntity) Dim BLLBasicdata As BasicDataBLL = New BasicDataBLL() Dim enbasicdata As New Entity.BasicDataEntity '調用返回基本資料函數,返回實體集合 basicdataList = BLLBasicdata.ReadBasic(enbasicdata) '調用職責鏈模式,計算上機時間 enline.consumeTime = onTimeCount.CostTime(basicdataList, enline)
分類:
這樣在自己的個人機房重構中就完整的對職責鏈模式熟悉了一遍,對於職責鏈的學習,也只是處於一個初級階段,這也純屬屬於“純的職責鏈模式(要麼承擔責任,要麼將責任全部推給下一家”,而且要求這個請求在過程結束之前必須能夠被一個處理者對象所接收;除此之外還有對應的“不純的職責鏈模式(允許某一個請求允許某個請求被一個具體處理者部分處理後再向下傳遞,或者一個具體處理者處理完某請求後其後繼處理者可以繼續處理該請求,而且一個請求可以最終不被任何處理者對象所接收)”未完