职责链模式应用——下机(机房重构知识点总结)
下机涉及两个方面,消费时间和消费金额。
对消费时间的处理用的是职责链模式,感觉这个模式用的非常妙,參考的师哥的博客:《机房收费下机中用到的策略与职责链解析》;消费金额的处理用策略模式。针对不同的用户类型。
这里着重介绍职责链的应用。
依据需求,将时间分为三个阶段,准备时间:不收取费用;至少上机时间:大于准备时间,小于至少上机时间的,一律按至少上机时间算。单位递增时间:大于至少上机时间后。按单位递增时间累加。
TimeHandler类,定义一个处理请示的接口
Public MustInherit Class TimeHandlerBLL Protected successor As TimeHandlerBLL Public Sub SetSuccessor(ByVal successor As TimeHandlerBLL) '设置继承者 Me.successor = successor End Sub Public MustOverride Function HandleTime(ByVal time As Integer) As Integer '处理请求的抽象方法 End Class
PrepareTimeHandler类。准备时间处理者,处理时间请求,假设能够处理就处理,否则把请求转给继承者
<pre class="vb" name="code">Public Class PrepareTimeHandlerBLL : Inherits TimeHandlerBLL Dim preparetime As Integer Public Sub New(ByVal esBasicData As List(Of Entity.BasicDataEntity)) '构造函数。传入准备时间的值 Me.preparetime = CInt(esBasicData(0).PrepareTime) End Sub Public Overrides Function HandleTime(time As Integer) As Integer '重写父类函数 If time <= preparetime Then '假设上机时间小于准备时间,返回0 Return 0 Else Return successor.HandleTime(time) '否则转到下一位继承者 End If End Function End Class
LeastTimeHandler类,同理
Public Class LeastTimeHandlerBLL : Inherits TimeHandlerBLL Dim leasttime As Integer Public Sub New(ByVal esBasicData As List(Of Entity.BasicDataEntity)) '构造函数,传递至少上机时间 Me.leasttime = CInt(esBasicData(0).LeastTime) End Sub Public Overrides Function HandleTime(time As Integer) As Integer '重写父类函数 If time <= leasttime Then Return leasttime '假设小于至少上机时间。返回至少上机时间 Else Return successor.HandleTime(time) '转到下一位 End If End Function End Class
StepTimeHandler类。处理剩余的请求
Public Class StepTimeHandlerBLL : Inherits TimeHandlerBLL Dim steptime As Integer Public Sub New(ByVal esBasicData As List(Of Entity.BasicDataEntity)) '构造函数,传递单位递增时间 Me.steptime = esBasicData(0).StepTime End Sub Public Overrides Function HandleTime(time As Integer) As Integer '大于至少时间。返回实际消费时间 Return Math.Abs(Int(-time / steptime)) * steptime End Function End Class
Math.Abs(Int(-time / steptime)) * steptime 这个地方看不明确的,參见博客:《史上最简洁的向上取整》
由于我这些代码写在B层,须要从U层调用。而參数须要通过实体来传递,所以添加一个类,在B层实例化类,既达到传实体的须要。又减少了U层与B层的耦合。
Public Class OnlineTimeBLL ''' <summary> ''' 上机时间处理------上下机 ''' </summary> ''' <param name="esBasicData">BasicDataEntity实体</param> ''' <param name="eOnlineRecord">OnlineRecordEntiry实体</param> ''' <returns>OnlineRecordEntiry实体</returns> ''' <remarks>刘晓春 2014年6月26日</remarks> Public Function CostTime(ByVal esBasicData As List(Of Entity.BasicDataEntity), eOnlineRecord As Entity.OnlineRecordEntiry) '实例化类,通过构造函数,传递參数 Dim bPrepareTime As New BLL.PrepareTimeHandlerBLL(esBasicData) Dim bLeastTime As New BLL.LeastTimeHandlerBLL(esBasicData) Dim bStepTime As New BLL.StepTimeHandlerBLL(esBasicData) bPrepareTime.SetSuccessor(bLeastTime) '设置职责链继承者 bLeastTime.SetSuccessor(bStepTime) Dim time As Integer '计算上下机时间差 time = DateDiff("n", eOnlineRecord.OnTime, eOnlineRecord.OffTime) + DateDiff("n", eOnlineRecord.OnDate, eOnlineRecord.OffDate) eOnlineRecord.CostTime = bPrepareTime.HandleTime(time) '职责链处理,返回消费时间 Return eOnlineRecord End Function End Class
DateDiff("n", eOnlineRecord.OnTime, eOnlineRecord.OffTime) + DateDiff("n", eOnlineRecord.OnDate, eOnlineRecord.OffDate) 这里分别计算日期和时间的差,然后求和,经測试。小的时间减大的时间会得出负值。再和日期得出的值相加,准确可靠。
然后是U层调用的代码:
Dim eOnlineRecord As New Entity.OnlineRecordEntiry '上机记录实体,传递上下机时间 eOnlineRecord.CardNo = esOnline(0).CardNo eOnlineRecord.OnDate = esOnline(0).OnDate eOnlineRecord.OnTime = esOnline(0).OnTime eOnlineRecord.OffDate = Format(DateTime.Now, "yyyy/MM/dd") eOnlineRecord.OffTime = Format(DateTime.Now, "HH:mm:ss") Dim bOnlineTime As New BLL.OnlineTimeBLL eOnlineRecord = bOnlineTime.CostTime(esBasicData, eOnlineRecord) '调用函数。传递实体
关于日期时间的格式。也须要我们特别注意,这里有篇博客不错。大家有须要的能够參考下:《VB.net中时间和日期的格式化》
职责链的应用到此就结束了,初学设计模式。有什么不正确的地方,欢迎大家批评指正。