策略模式的实例学习

现在合作开发机房收费系统,需要进一步地研究设计模式,发现真地用过了,不管用的好不好,理解起来会容易很多,收获的也大不一样。下面我就写写策略模式的使用。

1.什么时候使用策略模式?

策略模式的概念和UML图在之前的博客中写过,这里不再重复。主要想说一下什么时候使用策略模式。

策略模式是一种定义一系列算法的方法,从概念上看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少各种算法类与使用算法类之间的耦合。在机房收费系统中我在计算固定用户和临时用户的上机消费的地方 使用了策略模式。

2.机房收费系统中使用策略模式的UML图

在外观层中类图为:


在BLL层中的类图为:


3.实现的代码

U层:

......
        dt1 = subBasicValidate.ExistCardNo(enCard.CardNo)   '得到卡的类型

        Dim csuper As CashText = New CashText(dt1.Rows(0)(3))  '根据传入的参数决定实例化哪一个?
        Dim cash As Decimal
        cash = csuper.GetResult(enCard.CardNo)
Facade层:

Public Class CashText
    Dim consumeCash As BLL.CashSuperBLL = Nothing
    Sub New(ByVal cardType As String)
        Select Case cardType
            Case "固定用户"
                Dim confirmCash As BLL.ConfirmUser = New BLL.ConfirmUser
                consumeCash = confirmCash

            Case "临时用户"
                Dim tmpCash As BLL.TmpUser = New BLL.TmpUser
                consumeCash = tmpCash
        End Select
    End Sub

    Public Function GetResult(ByVal cardNo As String) As Decimal
        Return consumeCash.ConsumeCash(cardNo)
    End Function
End Class
B层:

Public MustInherit Class CashSuperBLL
    ''' <summary>
    ''' 计算出消费金额
    ''' </summary>
    ''' <param name="cardNo">卡号</param>
    ''' <returns>Decimal</returns>
    ''' <remarks></remarks>
    Public MustOverride Function ConsumeCash(ByVal cardNo As String) As Decimal
End Class

Public Class ConfirmUser
    Inherits CashSuperBLL
    ''' <summary>
    ''' 计算一个固定用户类型的卡号所花费的钱
    ''' </summary>
    ''' <param name="cardNo">卡号</param>
    ''' <returns>Decimal</returns>
    ''' <remarks></remarks>
    Public Overrides Function ConsumeCash(cardNo As String) As Decimal
        Dim subBasicData As New BLL.SubUsersManagerBLL
        Dim subOnOff As New BLL.SubOnOffBLL
        Dim dt As New DataTable
        Dim dt1 As New DataTable

        Dim unitPrice As Decimal
        Dim onTime As DateTime
        Dim offTime As DateTime
        Dim interval As Integer
        Dim n As Integer
        Dim f As Single

        dt = subBasicData.SelectBasicData()    '从基本数据表中查询出固定用户的单价。
        dt1 = subOnOff.SelStuOnOff(cardNo)     '查询该卡号的上下机记录
        unitPrice = dt.Rows(0)(0)
        onTime = Convert.ToString(dt1.Rows(0)(1))
        offTime = Convert.ToString(dt1.Rows(0)(3))

        interval = DateDiff(DateInterval.Second, onTime, offTime)   '计算出上机和下机之间的时间差

        If interval >= 0 And interval <= dt.Rows(0)("prepareTime") Then    '时间差在0和准备时间之间则不收费
            Return 0.0
        ElseIf dt.Rows(0)("unitTime") <> 0 Then  '保证分母不为零.
            n = interval \ dt.Rows(0)("unitTime")       '取整
            f = interval Mod dt.Rows(0)("unitTime")     '取余,判断余数大不大与最少上机时间,若大于则进。
            If f >= dt.Rows(0)("leastTime") Then
                n = n + 1
            End If
            Return n * unitPrice                  '单价*固定半小时费用
        Else
            MsgBox("分母不能为零", vbOKOnly, "温馨提示")
            Return 0.0
        End If
    End Function
End Class
临时用户的算法跟固定用户只是单位时间费用的区别,这里不给出代码。

4.总结

每一遍学习设计模式,都有不同的收获。在这个模式的学习里:看到一句话很兴奋:“封装变化点”。联想之前的经验,感觉面向对象三大特征真是精辟。继承的是类中不会变化的地方,变化的地方写死了就没有灵活性了。通过封装变化点,让根据需求带来的变化应对自如。当然封装本身就很有学问。而多态,个人片面理解就是解决继承中的灵活使用子类的问题。



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值