您的位置:首页 > 其它

【机房重构】--职责链模式+策略模式 实现下机

2017-05-29 17:22 316 查看

前言

下机的过程中主要涉及到按照消费时间分段计费,不同类型用户收费标准不同,以及下机后更新相关表的操作。 针对这三个要点,我分别采用了职责链模式实现消费分段计费,策略模式实现不同用户不同收费标准,更新多张表用到了存储过程。因为职责链模式在上机中用到过,所以这篇博文主要分析策略模式在下机中的应用。关于存储过程的研究,下篇博客再做展示。

why 策略模式?

大家都记得大话设计模式中超市收费的例子,正常计费,打折计费,返券计费分别是三钟不同的计费方式,将三种算法各自封装,他们之间可以互相调换,也就是根据用户所满足的条件,采用不同的算法。

UML图

这张图片是下机时采用策略模式的结构图。



Demo –下机

UI

''' <summary>
''' 下机
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub btnOffline_Click(sender As Object, e As EventArgs) Handles btnOffline.Click

Dim offlineInfo As New Entity.LineEntity
'给实体里面传入下机时间
Dim currentDate As DateTime = DateTime.Now
Dim result As Boolean
offlineInfo.CardNo = txtCardno.Text
offlineInfo.OffDate = currentDate.ToShortDateString
offlineInfo.OffTime = currentDate.ToLongTimeString

'获取卡号相关的上机信息
Dim OfflineList As List(Of Entity.LineEntity)
Dim DataBaseList As List(Of Entity.DataBaseEntity)           ' 基本数据设定表内容
Dim FacBasicdata As New Facade.T_DataBaseFacade
Dim DataBaseInfo As New Entity.DataBaseEntity
Dim FacStrategy As New Facade.T_LineFacade.CashContext     '策略模式
Dim FacLine As New Facade.T_LineFacade

OfflineList = FacLine.checkoninfo(offlineInfo)          ' 获取正在上机的卡号信息: 时间,卡号类型, 余额
Dim n As Integer = OfflineList.Count   '目的是获取返回的泛型记录里面最后一条记录的信息,也就是本次上机记录的信息
DataBaseList = FacBasicdata.displayDB(DataBaseInfo)     '调用基本信息表的外观得到基本信息表信息
offlineInfo.CardType = OfflineList(n - 1).CardType
offlineInfo.ConsumeTime = FacLine.costTime(DataBaseList, offlineInfo)   '使用职责链模式 ,传入参数
offlineInfo.ConsumeCash = FacStrategy.GetResult(DataBaseList, offlineInfo)   '使用策略模式,传入参数
offlineInfo.RemainCash = (CDec(OfflineList(n - 1).RemainCash) - CDec(offlineInfo.ConsumeCash)).ToString
offlineInfo.IsCheck = "未结账"

offlineInfo.OnDate = OfflineList(n - 1).OnDate
offlineInfo.OnTime = OfflineList(n - 1).OnTime
offlineInfo.StudentNo = OfflineList(n - 1).StudentNo
offlineInfo.StudentName = OfflineList(n - 1).StudentName
offlineInfo.Departmen = OfflineList(n - 1).Departmen
offlineInfo.Sex = OfflineList(n - 1).Sex

result = FacLine.updateInfo(offlineInfo)
If result <> 0 Then
txtOffdate.Text = offlineInfo.OffDate.ToString
txtOfftime.Text = offlineInfo.OffTime.ToString
txtRemaincash.Text = offlineInfo.RemainCash.ToString
txtConmcash.Text = offlineInfo.ConsumeCash.ToString
txtConmtime.Text = offlineInfo.ConsumeTime.ToString
txtType.Text = offlineInfo.CardType
txtOndate.Text = offlineInfo.OnDate.ToString
txtOntime.Text = offlineInfo.OnTime.ToString
txtSex.Text = offlineInfo.Sex

MsgBox("下机成功")
Else
MsgBox("下机失败")
End If
'调用模块方法,清空
Call Rdim()
AllEmpty(arrayControl)
End Sub


Facade

''' <summary>
''' 职责链模式实现消费时间计算
''' </summary>
''' <remarks></remarks>
Public Class T_LineFacade
Public Function costTime(ByVal DataBaseInfo As List(Of Entity.DataBaseEntity), LineInfo As Entity.LineEntity) As Integer
'实例化,通过构造函数,传递参数
Dim bPrepareTime As New BLL.T_LineBLL.PrepareTimeHandler(DataBaseInfo)
Dim bLeastTime As New BLL.T_LineBLL.LeastTimeHandler(DataBaseInfo)
Dim bAddTime As New BLL.T_LineBLL.UnitTimeHandler

bPrepareTime.setsuccessor(bLeastTime)
bLeastTime.setsuccessor(bAddTime)

Dim time As Integer  '计算在线时间
time = DateDiff("n", LineInfo.OnTime, LineInfo.OffTime)
Return bPrepareTime.handleTime(time)
End Function

''' <summary>
''' 抽象基类--
''' </summary>
''' <remarks>策略模式</remarks>

Public MustInherit Class CashSuper

Public MustOverride Function GetConsumeMoney(ByVal DataBaseInfo As List(Of Entity.DataBaseEntity), ByVal OffInfo As LineEntity) As Single

End Class
''' <summary>
''' --抽象策略
''' </summary>
''' <remarks></remarks>
Public Class CashContext
Dim cashsuper As CashSuper
'根据收费策略的不同,获得计算结果
Public Function GetResult(ByVal DataBaseInfo As List(Of Entity.DataBaseEntity), ByVal OfflineInfo As Entity.LineEntity) As Single
Select Case OfflineInfo.CardType.Trim()
Case "固定用户"
cashsuper = New StaUser()    '实例化具体策略
Case "临时用户"
cashsuper = New TmpUser()
Case Else
cashsuper = Nothing
End Select
Return cashsuper.GetConsumeMoney(DataBaseInfo, OfflineInfo)
End Function
End Class

''' <summary>
''' 具体策略--临时用户
''' </summary>
''' <remarks></remarks>
Public Class TmpUser : Inherits CashSuper
Dim strTmpRate As Single
Public Overrides Function GetConsumeMoney(DataBaseInfo As List(Of DataBaseEntity), OffInfo As LineEntity) As Single
strTmpRate = Trim(Int(DataBaseInfo(0).tmpRate))
Dim consumeCash As Single
consumeCash = Trim(Val(strTmpRate * Val(OffInfo.ConsumeTime * 1.0 / 60.0)))
If consumeCash < Int(DataBaseInfo(0).tmpRate) Then
consumeCash = Int(DataBaseInfo(0).tmpRate)
End If
Return consumeCash
End Function
End Class
''' <summary>
''' 具体策略--固定用户
''' </summary>
''' <remarks></remarks>
Public Class StaUser : Inherits CashSuper
Dim strStaRate As Single
Public Overrides Function GetConsumeMoney(DataBaseInfo As List(Of DataBaseEntity), OffInfo As LineEntity) As Single
strStaRate = Trim(Int(DataBaseInfo(0).staRate))
Dim consumeCash As Single
consumeCash = Trim(Val(strStaRate * Val(OffInfo.ConsumeTime * 1.0 / 60.0)))
If consumeCash <= Trim(Int(DataBaseInfo(0).staRate)) Then
consumeCash = Trim(Int(DataBaseInfo(0).staRate))
End If
Return consumeCash
End Function
End Class


BLL

''' <summary>
''' 消费时间确定--抽象基类
''' </summary>
''' <remarks>职责链模式</remarks>
Public MustInherit Class TimeHandler
Protected successor As TimeHandler
Public Sub setsuccessor(ByVal successor As TimeHandler)  '设置继承类
Me.successor = successor
End Sub
Public MustOverride Function handleTime(ByVal time As Integer) As Integer   '处理请求的抽象方法
End Class

''' <summary>
''' 子类--准备时间处理
''' </summary>
''' <remarks></remarks>
Public Class PrepareTimeHandler : Inherits TimeHandler
Dim preparetime As Integer
Public Sub New(ByVal BasicDataInfo As List(Of Entity.DataBaseEntity))
Me.preparetime = CInt(BasicDataInfo(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

''' <summary>
''' 子类--至少上机时间处理
''' </summary>
''' <remarks></remarks>

Public Class LeastTimeHandler : Inherits TimeHandler
Private leasttime As Integer
Public Sub New(ByVal BasicdataInfo As List(Of Entity.DataBaseEntity))
Me.leasttime = CInt(BasicdataInfo(0).leastTime)      '将基础数据赋给leastime变量
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

''' <summary>
''' 子类--计算消费时间
''' </summary>
''' <remarks></remarks>
Public Class UnitTimeHandler : Inherits TimeHandler

Public Overrides Function handleTime(time As Integer) As Integer
Return time
End Function
End Class


总结

加上两个设计模式让程序更加的简洁有范,职责链模式将多个计算判断分支抽象成多个类,获取的time再通过这些子类在链条进行判断,解决了下机中因为多个分支判断造成的灵活性差的问题。这样逻辑上也清晰很多。 策略模式让用户根据类型确定不同计费策略,封装算法,算法变化不会影响到客户,更简洁方便。设计模式都是超好用的套路,时机合适就多用套路。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: