考试期间一直想把策略模式加入到下机时,但一直看、一直想怎么都加不上。直到假期开始后,心里平静了许多,按着自己对策略模式的理解把模式加入到系统中去了,虽然还不是特别的完善,但符合我的设计要求,觉得还是很不错。下面就来介绍一下策略模式在机房收费系统中的应用!
策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
—抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
—具体策略角色:包装了相关的算法和行为。
—环境角色:持有一个策略类的引用,最终给客户端调用。
优点:
1、提供了一种替代继承的方法,而且既保持了继承的优点(代码重用)还比继承更灵活(算法独立,可以任意扩展)。
2、避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展。
3、高内聚、低偶合。
缺点:
1、因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量。
解决方案:工厂方法
固定用户和临时用户的收费方式相当于strategy,而固定用户和临时用户单个收费方式则是具体的策略concretestrategy。
Imports Entity Public MustInherit Class CashSuperBLL Public MustOverride Function GetConsumeMoney(ByVal sngB As Single, ByVal enLine As LineEntity, enBasic As BasicDataEntity, enCard As CardEntity) As Single End Class
<span style="font-size:18px;">Imports Entity Public Class FixedCashBLL : Inherits CashSuperBLL ''' <summary> ''' 固定用户 ''' </summary> ''' <param name="sngB"></param> ''' <param name="enLine"></param> ''' <param name="enBasic"></param> ''' <param name="enCard"></param> ''' <returns></returns> ''' <remarks></remarks> Public Overrides Function GetConsumeMoney(sngB As Single, enLine As LineEntity, enBasic As BasicDataEntity, enCard As CardEntity) As Single Dim sngConsumeMoney As Single Select Case sngB Case Is <= 0 '消费时间小于0 enCard.RegisterMoney = enCard.RegisterMoney sngConsumeMoney = 0 Case Is <= enBasic.LeastTime '消费时间消费时间小于设定最少时间 enCard.RegisterMoney = enCard.RegisterMoney - enBasic.FixUserHalfHourCost sngConsumeMoney = enBasic.FixUserHalfHourCost Case Is > enBasic.LeastTime '消费时间大于设定最少时间 enCard.RegisterMoney = enCard.RegisterMoney - sngB / 30 * enBasic.FixUserHalfHourCost sngConsumeMoney = sngB / 30 * enBasic.FixUserHalfHourCost End Select Return sngConsumeMoney End Function End Class</span>
<span style="font-size:18px;">Public Class TempCashBLL : Inherits CashSuperBLL ''' <summary> ''' 临时用户 ''' </summary> ''' <param name="sngB"></param> ''' <param name="enLine"></param> ''' <param name="enBasic"></param> ''' <param name="enCard"></param> ''' <returns></returns> ''' <remarks></remarks> Public Overloads Overrides Function GetConsumeMoney(sngB As Single, enLine As Entity.LineEntity, enBasic As Entity.BasicDataEntity, enCard As Entity.CardEntity) As Single Dim sngConsumeMoney As Single Select Case sngB Case Is <= 0 '消费时间小于0 enCard.RegisterMoney = enCard.RegisterMoney sngConsumeMoney = 0 Case Is <= enBasic.LeastTime '消费时间消费时间小于设定最少时间 enCard.RegisterMoney = enCard.RegisterMoney - enBasic.TemporaryUserHourCost sngConsumeMoney = enBasic.TemporaryUserHourCost Case Is > enBasic.LeastTime '消费时间大于设定最少时间 enCard.RegisterMoney = enCard.RegisterMoney - sngB / 30 * enBasic.TemporaryUserHourCost sngConsumeMoney = sngB / 30 * enBasic.TemporaryUserHourCost End Select Return sngConsumeMoney End Function End Class</span>
<span style="font-size:18px;">Imports Entity Public Class ContextCalculateBLL Private cs As CashSuperBLL = Nothing Public Sub New(ByVal cardType As String, ByVal sngB As Single) Select Case (cardType) Case "固定用户" cs = New FixedCashBLL() Exit Sub Case "临时用户" cs = New TempCashBLL() Exit Sub End Select End Sub Public Function GetResult(ByVal sngB As Single, enLine As LineEntity, enBasic As BasicDataEntity, enCard As CardEntity) Return cs.GetConsumeMoney(sngB, enLine, enBasic, enCard) End Function End Class</span>
<span style="font-size:18px;"> Private Sub btnOutLine_Click(sender As Object, e As EventArgs) Handles btnOutLine.Click Dim fadLine As New Facade.LineFacade Dim fadBasic As New Facade.BasicDataFacade Dim sngReceive As Single Dim sngH As Single Dim sngM As Single Dim d As Date Dim sngConsumeTime As Integer Dim dtReceive As DataTable Dim dtOutLine As New DataTable Dim enBasic As New BasicDataEntity Dim enOnLine As New LineEntity Dim enCard As New CardEntity Try enCard.CardID = txtCardID.Text.Trim enOnLine.CardID = txtCardID.Text.Trim d = Trim(Format(Now, "hh:mm")) dtReceive = fadLine.GetOnLine(enOnLine) sngH = (DateDiff(DateInterval.Hour, dtReceive.Rows(0)(4), d) * 60) sngM = DateDiff(DateInterval.Minute, dtReceive.Rows(0)(4), d) sngConsumeTime = sngM + sngH 'enOnLine.OutTime = Trim(Format(Now, "hh:mm")) '获得基本数据设定窗体中的值 enBasic.FixUserHalfHourCost = FrmMDI.sngFixedHalfHourCost enBasic.TemporaryUserHourCost = FrmMDI.sngTempHourCost enBasic.IncreaseTime = FrmMDI.sngIncreaseTime enBasic.LeastTime = FrmMDI.sngLeastTime enBasic.LeastMoney = FrmMDI.sngLeastMoney enBasic.PrepareTime = FrmMDI.sngPrepareTime '将相应的值传入外观,调用相应的策略模式 sngReceive = fadLine.GetConsumMoney(enOnLine, sngConsumeTime, enBasic, enCard) enOnLine.OutDate = Trim(Format(Now, "yyyy-MM-dd")) enOnLine.OutTime = Trim(Format(Now, "hh:mm")) enOnLine.ConsumeTime = sngConsumeTime enOnLine.ConsumeMoney = sngReceive enOnLine.NowCardBalance = enCard.RegisterMoney - sngReceive '将实体中的值传递,写入到相应的表中 dtOutLine = fadLine.OutLine(enOnLine, enCard) '在界面上显示下机相应的值 txtConsumeTime.Text = sngConsumeTime txtConsumeMoney.Text = sngReceive txtRegisterbalance.Text = enCard.RegisterMoney - sngReceive txtOutDate.Text = Trim(Format(Now, "yyyy-MM-dd")) txtOutTime.Text = Trim(Format(Now, "hh:mm")) txtOnDate.Text = enOnLine.OnDate txtOnTime.Text = enOnLine.OnTime txtStudentID.Text = dtOutLine.Rows(0)("studentID") txtStudentName.Text = dtOutLine.Rows(0)("studentName") txtDepartment.Text = dtOutLine.Rows(0)("department") txtDepartment.Text = dtOutLine.Rows(0)("sex") txtNotes.Text = dtOutLine.Rows(0)("notes") MsgBox("成功下机!") Catch ex As Exception MsgBox(ex.Message) End Try</span>
<span style="font-size:18px;">Public Function GetConsumMoney(enLine As LineEntity, sngConsumeTime As Single, enBasic As BasicDataEntity, enCard As CardEntity) As Single Dim bllCheck As New LineBLL Dim dtReceive As New DataTable Dim dtNotes As New DataTable Dim bllGet As New CardBLL '判断该卡是否上机 dtReceive = bllCheck.CheckOnLine(enLine) If dtReceive.Rows.Count < 1 Then Throw New Exception("本卡并未上机") Exit Function End If enLine.OnDate = dtReceive.Rows(0)("loginDate") enLine.OnTime = dtReceive.Rows(0)("loginTime") '取出卡相应的值 dtNotes = bllGet.QueryIsExist(enCard) enLine.Notes = dtNotes.Rows(0)("Notes") enCard.RegisterMoney = dtNotes.Rows(0)("registerMoney") '调用策略模式 Dim Result As Double Dim OffAccount As New ContextCalculateBLL(enLine.Notes, sngConsumeTime) Result = OffAccount.GetResult(sngConsumeTime, enLine, enBasic, enCard) Return Result End Function</span>B层与D层的设计与以往的相同
策略模式的添加和大家的不太一样,如果有什么不正确的,望斧正!