策略模式实战

        考试期间一直想把策略模式加入到下机时,但一直看、一直想怎么都加不上。直到假期开始后,心里平静了许多,按着自己对策略模式的理解把模式加入到系统中去了,虽然还不是特别的完善,但符合我的设计要求,觉得还是很不错。下面就来介绍一下策略模式在机房收费系统中的应用!

一、策略模式

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

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层的设计与以往的相同

        策略模式的添加和大家的不太一样,如果有什么不正确的,望斧正!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 15
    评论
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值