职责链模式应用——下机(机房重构知识点总结)

    下机涉及两个方面,消费时间和消费金额。对消费时间的处理用的是职责链模式,感觉这个模式用的很妙,参考的师哥的博客:《机房收费下机中用到的策略与职责链解析》;消费金额的处理用策略模式,针对不同的用户类型。

    这里着重介绍职责链的应用。

    根据需求,将时间分为三个阶段,准备时间:不收取费用;至少上机时间:大于准备时间,小于至少上机时间的,一律按至少上机时间算;单位递增时间:大于至少上机时间后,按单位递增时间累加。

 

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中时间和日期的格式化》

 

    职责链的应用到此就结束了,初学设计模式,有什么不对的地方,欢迎大家批评指正。

 

 

 

 

 

 

你可能感兴趣的:(职责链模式,机房收费系统)