考试期间一直想把策略模式加入到下机时,但一直看、一直想怎么都加不上。直到假期开始后,心里平静了许多,按着自己对策略模式的理解把模式加入到系统中去了,虽然还不是特别的完善,但符合我的设计要求,觉得还是很不错。下面就来介绍一下策略模式在机房收费系统中的应用!
一、策略模式
1、介绍
策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
—抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
—具体策略角色:包装了相关的算法和行为。
—环境角色:持有一个策略类的引用,最终给客户端调用。
2、图分析
3、优缺点
优点:
1、提供了一种替代继承的方法,而且既保持了继承的优点(代码重用)还比继承更灵活(算法独立,可以任意扩展)。
2、避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展。
3、高内聚、低偶合。
缺点:
1、因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量。
解决方案:工厂方法
二、机房收费系统中的下机功能
固定用户和临时用户的收费方式相当于strategy,而固定用户和临时用户单个收费方式则是具体的策略concretestrategy。
1、Stragedy类
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
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
2、固定用户
<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>
3、临时用户
<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>
4、Constext类
<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>
5、U层
<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>
6、F层
<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层的设计与以往的相同
策略模式的添加和大家的不太一样,如果有什么不正确的,望斧正!