【机房重构】--职责链模式+策略模式 实现下机
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再通过这些子类在链条进行判断,解决了下机中因为多个分支判断造成的灵活性差的问题。这样逻辑上也清晰很多。 策略模式让用户根据类型确定不同计费策略,封装算法,算法变化不会影响到客户,更简洁方便。设计模式都是超好用的套路,时机合适就多用套路。相关文章推荐
- [置顶] 【机房重构】下机——职责链模式+策略模式(实践篇)
- 【机房重构】--职责链模式实现上机
- 机房重构---下机(策略模式和职责连模式)
- 机房重构利用策略模式+简单工厂实现消费金额的计算
- 机房重构利用策略模式+简单工厂实现消费金额的计算
- 机房重构——下机(职责链模式+策略模式)
- 机房重构时利用状态模式实现消费时间的计算
- 【机房重构】——策略模式+简单工厂计算消费
- 机房重构时利用状态模式实现消费时间的计算
- 机房重构之职责链模式
- 机房合作——策略、职责链模式下机
- 机房收费系统重构之策略模式
- 【个人机房重构】策略模式在下机
- 机房合作——职责链+策略模式
- 【机房重构】职责链模式之上机
- 重构桌面飘着圣诞老人,利用策略模式和改造的代理模式让软件完全实现开闭原则,欢迎下载源代码分析
- Dongle烧写模块重构(三)--用策略模式自定行为框架,再交由方案商实现
- 机房重构版——上下机判断卡号实现职责链模式。
- 机房重构—策略模式简单用
- 机房重构下机之策略模式