[置顶] 个人机房重构——下机与职责链的结合

         个人机房重构中加入设计模式让我们的代码更加灵活,减少耦合。在下机过程中,我使用了职责链模式,当然,还有很多模式适合下机这个功能的实现,期待大家的灵活运用。在此,我用把职责链模式在下机功能中的应用分享给大家,共同交流学习。

职责链模模式

职责链模式(Chain of Respoonsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象练成一条链,并沿着这条链传递该请求,知道有一个对象处理它为止。

我们来看一看结构图

[置顶] 个人机房重构——下机与职责链的结合_第1张图片



功能:职责链模式的运用,解决了当用户提交一个请求时,请求是沿链传递直至有一个ConcreteHandler对象负责处理它,这就使得接受者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构。结构是职责链可简化对象的相互连接,他们仅需保持一个纸箱其后继者的引用,而不需保持他所有的候选者的引用,这样就大大的降低了耦合度。我们可以随时的增加或修改处理一个请求的结构。增强了给对象指派指责的灵活性。

下机与职责链的结合

我们知道,下机操作在机房收费系统中有三种不同的下机方式,即,输入卡号下机;选中下机和全部下机。所以,我将下机过程定义成一个过程,这就大大的简化了代码。

    Protected Sub OffLine(ByVal CardNo As String)
        Dim dt As New DataTable
        Dim fac As New Facade.InqOnLineFacade
        Dim intoff As Integer

        '存储花费时间()
        Dim date1 As Integer
        Dim time1 As Integer

        '检查卡号是否正在上机
        showline.CardNo = CardNo              '从过程外传递的参数,也就是卡号
        showline.OutTime = Format(TimeOfDay, "HH:mm:ss")
        showline.OutDate = DateTime.Now.ToString("yyyy-MM-dd")
              
        dt = fac.ShowOff(showline)         

        If dt.Rows.Count <= 0 Then
            MsgBox("该卡号没有上机,请仔细核对卡号!", , "提示!")
            txtCardNum.Text = ""
        Else

            showline.Type = dt.Rows(0).Item(3)                             '获得该卡号上机存入数据库的数据
            showline.OnDate = dt.Rows(0).Item(1)
            showline.OnTime = dt.Rows(0).Item(2)
            'showline.OutTime = Format(TimeOfDay, "HH:mm:ss")
            showline.OutTime = TimeOfDay()                               '下机时间
            showline.OutDate = DateTime.Now.ToString("yyyy-MM-dd")       '下机日期


            date1 = DateDiff("n", showline.OnDate, showline.OutDate)     '计算上机的天数
            time1 = DateDiff("n", showline.OnTime, showline.OutTime)     '计算上机的时长(单位:分钟)

            showline.ConsumeTime = date1 + Math.Abs(time1)                      '总上机时间


            showline = fac.Count(showline)         '计算消费金额(职责链模式)

            showline.CardNo = CardNo
            intoff = fac.InsertOff(showline)       '将消费信息存入数据库


            '刷新正在上机人数   
            showline.dtNum = 6

            dt = fac.ShowOn(showline)

            txtOnNum.Text = dt.Rows(0).Item(0)        '将数据传递给文本框,显示当前上机人数

            Call ShowOn(dgvOffLine)         '刷新当前上机卡号的数据
        End If
    End Sub

全部下机的调用过程:

    Private Sub btnAllOff_Click(sender As Object, e As EventArgs) Handles btnAllOff.Click
        Dim i As Integer
        Dim CardNo As Integer               '定义卡号
                       
        For i = 0 To dgvOffLine.Rows.Count - 1      '循环第一行的卡号
            CardNo = dgvOffLine.Rows(0).Cells(0).Value.ToString()
            Call OffLine(CardNo)          
        Next
        MsgBox("全部下机成功!", , "提示")
    End Sub

使用职责链模式的外观层

    '计算下机费用
    Function Count(showline As Entity.OnLineEntity) As Entity.OnLineEntity
        Dim Bfirst As New BLL.FirstCashBLL
        Dim cash As Entity.OnLineEntity
        Dim Bsecond As New BLL.SecondCashBLL      
        Dim Bthird As New BLL.ThirdCashBLL

        Bfirst.SetSuperior(Bsecond)         '设置上级,完全可以根据实际需求来更改设置
        Bsecond.SetSuperior(Bthird)


        cash = Bfirst.GetCash(showline)     '进行计算
        

        Return cash
    End Function

B层的逻辑处理类

父类

'计算上机花费金额的父类
Public MustInherit Class Manager

    Protected superior As Manager

    '管理者的上级,即所有计算金额的父类
    Public Sub SetSuperior(ByVal superior As Manager)
        Me.superior = superior
    End Sub

    '计算所花费的金额
    Public MustOverride Function GetCash(ByVal showline As Entity.OnLineEntity) As Entity.OnLineEntity

End Class

各个逻辑处理子类

'计算第一步时间间隔所花费的时间
Public Class FirstCashBLL
    Inherits Manager

    Public Overrides Function GetCash(showline As Entity.OnLineEntity) As Entity.OnLineEntity
        If showline.ConsumeTime <= (showline.LeastCash + showline.ReadyTime) Then    '如果上机时间小于准备时间+最小上机时间
            showline.ConsumeCash = 0
        Else
            superior.GetCash(showline)          '传给下一级
        End If

        Return showline
    End Function
End Class

Public Class SecondCashBLL
    Inherits Manager

    '计算未达到单位上机时间的所消费金额
    Public Overrides Function GetCash(showline As Entity.OnLineEntity) As Entity.OnLineEntity     
        If showline.ConsumeTime > (showline.LeastCash + showline.ReadyTime) And showline.ConsumeTime <= showline.IncreaseTime Then

            If showline.Type = "固定用户" Then
                showline.ConsumeCash = showline.RegularUser        '固定用户
            Else
                showline.ConsumeCash = showline.CasualUser      '临时用户
            End If
        Else
            superior.GetCash(showline)           '传递给下一个判断语句
        End If

        Return showline
    End Function
End Class

Public Class ThirdCashBLL
    Inherits Manager

    '计算未达到单位上机时间的所消费金额
    Public Overrides Function GetCash(showline As Entity.OnLineEntity) As Entity.OnLineEntity
        Dim x As Integer   '取整
        Dim y As Integer   '取余


        x = showline.ConsumeTime \ showline.IncreaseTime              '单位时间内获得的整数
        y = showline.ConsumeTime Mod showline.IncreaseTime            '取单位时间内除得的余数

        If showline.Type = "固定用户" Then
            If y = 0 Then              '如果余数=0,则正常计算
                showline.ConsumeCash = (showline.RegularUser / (60 / showline.IncreaseTime)) * x        '固定用户花费金额
            ElseIf y > 0 And y < showline.IncreaseTime Then         '如果小于单位递增时间,则按照单位递增时间算
                showline.ConsumeCash = (showline.RegularUser / (60 / showline.IncreaseTime)) * (x + 1)
            End If
        Else
            If y = 0 Then
                showline.ConsumeCash = (showline.CasualUser / (60 / showline.IncreaseTime)) * x        '临时用户花费金额
            ElseIf y > 0 And y < showline.IncreaseTime Then
                showline.ConsumeCash = (showline.CasualUser / (60 / showline.IncreaseTime)) * (x + 1)
            End If
        End If


        Return showline
    End Function
End Class


总结:下机功能通过使用职责链模式,将很多的计算判断分支抽象成不同的类,并通过上下级的设置使得数据沿着职责链进行判断,非常好的解决了原来大量的分支判断造成的难维护、灵活性差的问题。在以后的机房合作中,应该考虑各个方面,在下机的过程中还有很多好的设计模式可以利用起来,期待着以后的设计模式与下机的结合。




你可能感兴趣的:([置顶] 个人机房重构——下机与职责链的结合)