首页 > 代码库 > 机房重构时利用状态模式实现消费时间的计算

机房重构时利用状态模式实现消费时间的计算

在做机房重构时,我们会在学生上下机计算学生上机时间时,会出现消费时间随着基本数据设定表中的数据变化而变化,这里不仅仅是数据的变化,还包括不同时间段内消费时间具体确定问题。主要分为三个时间段的计算

1.准备时间:即在此时间段内,消费金额为0  

2.至少上机时间:如果上机时间超过了准备时间,但是少于至少上机时间,那么此时消费时间为至少上机时间

3.按正常消费时间来算:此时,消费时间大于至少上机时间后,则按照正常时间来算

通过对业务的分析,我们发现在不同时间段,最终的消费时间的计算方式是不一样的。如果我们就这样直接一条条分析的话,会出现很多if.....else语句,计算过程还会很复杂,这可不是什么好兆头。于是根据23设计模式中特点进行分析,发现使用状态模式或者指责链模式是可以解决分段处理的问题的,这两个模式的使用基本上是一样的,只是在职责链模式需要在客户端来定义下一个执行的具体子类,而状态模式直接定义在了正在执行的子类中。

具体实现如下:

Public MustInherit Class TimePeriod
    ''' <summary>
    ''' 计算消费时间的虚方法
    ''' </summary>
    ''' <remarks></remarks>
    Public MustOverride Sub CountTime(ByVal time As TimeState)

End Class
‘准备时间子类
Public Class ReadyTime : Inherits TimePeriod

    ''' <summary>
    ''' 准备时间的计算
    ''' </summary>
    ''' <param name="time">TimeState对象</param>
    ''' <remarks></remarks>
    Public Overrides Sub CountTime(time As TimeState)
        If time.costTime < time.stuReadyTime Then
            time.costTime = 0
        Else
            time.SetNextTimePeriod(New LeastTime()) '设置下一个时间段子类为至少上机时间
            time.AllCostTime()
        End If
    End Sub

End Class
’至少上机时间子类

Public Class LeastTime : Inherits TimePeriod
    ''' <summary>
    '''实现至少上机时间的计算
    ''' </summary>
    ''' <param name="time">TimeState对象</param>
    ''' <remarks></remarks>
    Public Overrides Sub CountTime(time As TimeState)
        If time.costTime <= time.stuLeastTime Then '如果小于最少上机时间
            time.costTime = time.stuLeastTime
        Else
            time.SetNextTimePeriod(New PerAddTime()) ’设置下一个时间段子类为正常消费时间段
            time.AllCostTime()
        End If
    End Sub

End Class
‘正常消费时间子类,即按正常增长时间计算

Public Class PerAddTime : Inherits TimePeriod
    ''' <summary>
    ''' 大于至少消费时间后,按正常消费时间计算
    ''' </summary>
    ''' <param name="time">引用timeState的一个对象</param>
    ''' <remarks></remarks>
    Public Overrides Sub CountTime(time As TimeState)
        '如果消费时间大于最低消费时间
        If time.costTime > time.stuLeastTime Then
            time.costTime = time.costTime
        End If
    End Sub
End Class
’TimeState类,相当于状态模式中的work类,其中定义一个构造方法,来实现最初时间段的选择。构造方法在执行类时,会同时执行构造方法
Public Class TimeState    Private timeCurrent As TimePeriod '先定义一个时间状态    Public Sub New()<span style="font-family: Arial; ">'定义一个构造方法,来初始化消费时间的时间段,最少为准备时间段</span>          timeCurrent = New ReadyTime() '初始化消费时间段    End Sub       '定义消费时间变量和属性    Private cost_Time As Decimal    ''' <summary>    ''' 消费时间属性,即为学生上下机记录中的消费时间    ''' </summary>    ''' <value></value>    ''' <returns></returns>    ''' <remarks></remarks>    Public Property costTime As Decimal        Set(value As Decimal)            cost_Time = value        End Set        Get            Return cost_Time        End Get    End Property    '定义一个表示数据信息实体中的准备时间    Private stuReady_Time As Decimal    Public Property stuReadyTime() As Decimal        Set(value As Decimal)            stuReady_Time = value        End Set        Get            Return stuReady_Time        End Get    End Property    '定义一个表示基本数据信息中最少花费时间的属性    Private stuLeast_Time As Decimal    Public Property stuLeastTime As Decimal        Set(value As Decimal)            stuLeast_Time = value        End Set        Get            Return stuLeast_Time        End Get    End Property   '定义一个方法,来设置接下来的时间状态,即消费时间区段    Public Sub SetNextTimePeriod(ByVal nexttime As TimePeriod)        timeCurrent = nexttime '指明下一个消费时间段    End Sub   '定义返回消费时间的方法    Public Sub AllCostTime()        timeCurrent.CountTime(Me)    End SubEnd Class

以上是主要涉及到状态模式的代码,其实通过对比,我们发现大部分是一样的,只是在context类中(即状态模式的work类)需要把我们实际要用到的参数进行声明。当然可以直接声明公开变量,而省去属性的声明。在客户端直接进行调用就可以了。

具体参数的获得略。依个人方法而定

  '利用状态模式,先实例化一个TimeState
            Dim work As New BLL.TimeState
            work.AllCostTime()
            txtConsumeTime.Text = work.costTime '利用状态模式获得消费时间,显示消费时间
通过这样,我们可以发现,在U层除了需要为所需要参数进行赋值外,就只剩下上面这短短的几行代码,就完全可以将消费时间这个功能实现。感觉舒服多了吧!

通过机房重构对设计模式的运用,发现只要去应用,设计模式还是很容易接受的,而且写出的代码感觉还是很舒服的。对学习过得知识,在这个过程中努力去应用!