在完成了VB.Net版的机房收费系统后,感觉自己对面向对象的认识实在是太少了,所以在网上搜集各种相关资料,添补这块知识的空白。
这不,经过一个上午的思索,终于把职责链模式加入了机房收费系统,进一步加深对面向对象思想的认识。
有需求才有动力,在完成机房收费系统时,有个计算消费时间的函数,当时功能是实现了,但没有体会到面向对象的思想,所以在此进行重构。
当我们计算消费时间OnlineTime时,需要将OnlineTime和准备时间PrepareTime、至少上机时间LeastTime、单位递增时间IncreaseTime进行比较。如果消费时间小于准备时间,则消费时间为0;如果消费时间大于准备时间小于至少上机时间,则消费时间为至少上机时间;如果消费时间大于至少上机时间,则按收费标准进行收费。
如果用If……else实现上述逻辑,代码混乱程度可想而知。如果我们用职责链模式实现,则思路变得非常清晰。职责链的核心就是按着一条链,依次执行,直到有对象处理了此事。
要想用职责链模式实现上述逻辑,首先我们要在准备时间、至少上机时间、单位递增时间的基础上进行抽象,抽象出抽象类OnlineTimeHandler,上边三者分别继承OnlineTimeHandler抽象类。
其中,抽象类OnlineTimeHandler代码如下:
Public MustInherit Class OnlineTimeHandler
'获得的消费时间
Protected onlineTime As Integer
'设置上下级
Property calculate As OnlineTimeHandler
'设置OnlineTimeHandler下级
Public Sub SetNext(ByVal calculate As OnlineTimeHandler)
Me.calculate = calculate
End Sub
'处理申请 MustOverride抽象
Public MustOverride Function Request(ByVal onlineTime As Integer) As Integer
End Class
准备时间PrepareTimeHandler类代码如下:
Public Class PrepareTimeHandler : Inherits OnlineTimeHandler
Private prepareTime As Integer
Public Sub New(ByVal prepareTime As Integer)
Me.prepareTime = prepareTime
End Sub
Public Overrides Function Request(ByVal onlineTime As Integer) As Integer
'如果上机时间小于准备时间,则上机时间为0,否则把信息传递到它的下属
If onlineTime <= prepareTime Then
Return 0
Else
Return calculate.Request(onlineTime)
End If
End Function
End Class
至少上机时间LeastTimeHandler类代码如下:
Public Class LeastTimeHandler : Inherits OnlineTimeHandler
Private leastTime As Integer
Public Sub New(ByVal leastTime As Integer)
Me.leastTime = leastTime
End Sub
Public Overrides Function Request(ByVal onlineTime As Integer) As Integer
'如果上机时间小于最少时间,则上机时间为最少时间,否则把信息传递到它的下属
If onlineTime < leastTime Then
Return leastTime
Else
Return calculate.Request(onlineTime)
End If
End Function
End Class
单位递增时间IncreaseTimeHandler类代码如下:
Public Class IncreaseTimeHandler : Inherits OnlineTimeHandler
Private increaseTime As Integer
Public Sub New(ByVal increaseTime As Integer)
Me.increaseTime = increaseTime
End Sub
Public Overrides Function Request(ByVal onlineTime As Integer) As Integer
Return onlineTime
End Function
End Class
程序main函数:
Sub Main()
'声明三个对象,并为对象设置初值
Dim a As New PrepareTimeHandler(2)
Dim b As New LeastTimeHandler(5)
Dim c As New IncreaseTimeHandler(10)
'设置a的下属为b,b的下属为c
a.SetNext(b)
b.SetNext(c)
'测试
Console.WriteLine(a.Request(1))
Console.WriteLine(a.Request(3))
Console.WriteLine(a.Request(6))
End Sub
这样,我们设置准备时间为2,至少上机时间为5,单位递增时间为10。当消费时间为1时,PrepareTimeHandler类直接处理掉此事,结果为0;当消费时间为3时,PrepareTimeHandler无法处理此事,把信息传递到它的下属LeastTimeHandler类,LeastTimeHandler可以处理此事,结果为5;当消费时间为6时,信息传递到InCreaseTimeHandler类,它处理此事。
输入结果如下:
通过上述过程,实现了职责链的功能。
希望我的讲解能对大家有所帮助。