现在的位置: 首页 > 综合 > 正文

策略模式

2013年10月30日 ⁄ 综合 ⁄ 共 3636字 ⁄ 字号 评论关闭

   在大话中,我们已经学习过策略模式,并且对书中的例子进行了实现。可是真到了此时,要将策略模式应用到机房收费系统中,感觉无从下手了。好在,还是很快的迈出了第一步--做!

   第一次在机房中加的设计模式就是抽象工厂,说实在的,那时候的感触远远没有现在加入策略模式大。其中最主要的原因就是--自我思考!抽象工厂是在网上参考他人经验后写的,可以说是比猫画虎吧,当时写完了也没有自己思考一下为什么别人要这么写,为什么别人可以自己写出来而自己却写不出来呢?现在要开始合作了,开始加策略模式,也是第一反应就是上网查资料,可是后来突然想到了抽象工厂的教训,于是断然关闭了网页,开始自己探索。

   很快的,不到一个上午的时间,初步在机房中加入了第一版的策略模式,个人感觉很良好,先不管对错,起码运行起来很完美。充分享受完这种自豪感后,还是和别人讨论了一下我的方法的对错。应该说是庆幸,在讨论后,我才知道,我实现了功能,却错误了过程,也错误了策略模式的初衷!为什么这么说呢?且听听我的第一遍思路吧:(不再展示具体代码)

     1.错误思路:将策略模式分层了!

    (1Context类放在B层,通过引用接口层来实现D层代码;

    (2Strategy类放在接口层(包含ConcreteStrategyAConcreteStrategyB两种具体策略的方法);

    (3ConcreteStrategyAConcreteStrategyB具体策略类以两种不同的方法,放在实现Strategy类的D层的类中。

         三者之间的联系是:接口层的Strategy类定义了抽象方法,没有具体实现;具体实现则在D层的具体策略类,如ConcreteStrategyA中;然后B层的Context类通过引用Strategy来实现D层具体策略类。

     2.错误原因:

    试想,如果这时候加入一个新的具体策略ConcreteStrategyC,我们需要更改接口层、B层和D层。违背了我们开放-封闭原则,没有体现出我们再此加入策略模式的优势。

 

   说了错误之后,就要展示一下正确的了。新的思路是整个策略模式都是在B层的,而且是一个具体策略一个类(而不像上述错误思路中,只有一个具体策略类,其中有不同的具体策略的方法),这两点是出入比较大的。

先向大家展示一下策略模式的代码结构图:

 

    

   这时候,我们可以通过图和上述正确思路发现:当业务逻辑修改,增加一个具体策略ConcreteStrategyC的时候,Context类、Strategy类、ConcreteStrategyAConcreteStrategyB类都是不需要改变的,只需要增加一个ConcreteStrategyC子类,继承Strategy父类即可。

   代码展示如下:

       1. CashContextBLL类:维护一个对UserTypeSuper抽象策略类的引用

'************************************************* 
'作者:孙丽端 
'说明:策略模式加简单工厂类
'创建日期:2013-9-8
'版本号:2.0
'*************************************************
Imports Entity
Imports DBFactory.SqlFactory
Imports IDAL

Public Class CashContextBLL
    '实例化抽象工厂类
    Public SqlFactory As New DBFactory.SqlFactory

    Public Function UserTypeExpense(ByVal UserType As String) As String
        '实例化一个CashSuper(抽象策略类)对象
        Dim CS As CashSuperBLL
        '定义用户每小时收费金额变量
        Dim UserTypeHourCost As String
        '实例化临时用户具体策略类
        Dim CasualStrategy As New CasualStrategyBLL
        '实例化固定用户具体策略类
        Dim FixedStrategy As New FixedStrategyBLL

        '根据"用户类型"的不同,选择不同的具体策略类
        Select Case UserType
            Case "临时用户"
                CS = CasualStrategy
            Case "固定用户"
                CS = FixedStrategy
        End Select

        '取得用户每小时收费金额
        UserTypeHourCost = CS.UserTypeExpenseMoney()
        Return UserTypeHourCost
    End Function
End Class

   2. UserTypeSuper抽象策略类

	'************************************************* 
	'作者:孙丽端 
	'说明:抽象策略接口类
	'创建日期:2013-9-8
	'版本号:1.0
	'*************************************************
	Imports Entity
	
	Public Interface UserTypeSuperBLL
	    ''' <summary>
	    ''' 根据不同用户类型计算消费金额
	    ''' </summary>
	    ''' <returns>返回字符串</returns>
	    ''' <remarks></remarks>
	    Function UserTypeExpenseMoney() As String
	End Interface

   3. CasualStrategy具体策略类

'************************************************* 
'作者:孙丽端 
'说明:临时用户具体策略类
'创建日期:2013-9-8
'版本号:1.0
'*************************************************
Imports Entity
Imports IDAL
Imports DBFactory.SqlFactory

Public Class CasualStrategyBLL
    Implements CashSuperBLL   '实现抽象策略类

    Public Function UserTypeExpenseMoney() As String Implements CashSuperBLL.UserTypeExpenseMoney
        Dim ICashSuper As IDAL.IBasciData
        Dim eBasciData As New BasciDataEntity
        Dim UserTypeHourCost As String
        '引用接口方法,得到临时用户每小时消费金额标准
        ICashSuper = DBFactory.SqlFactory.CreatBasciData
        eBasciData = ICashSuper.iQueryBasciData()
        UserTypeHourCost = eBasciData.CasualUserHourCost
        Return UserTypeHourCost
    End Function
End Class

   4. FixedStrategy具体策略类

'************************************************* 
'作者:孙丽端 
'说明:固定用户具体策略类
'创建日期:2013-9-8
'版本号:1.0
'*************************************************
Imports Entity
Imports IDAL
Imports DBFactory.SqlFactory

Public Class FixedStrategyBLL
    Implements CashSuperBLL   '实现抽象策略类

    Public Function UserTypeExpenseMoney() As String Implements CashSuperBLL.UserTypeExpenseMoney
        Dim ICashSuper As IBasciData
        Dim eBasciData As New BasciDataEntity
        Dim UserTypeHourCost As String
        '引用接口方法,得到固定用户每小时消费金额标准
        ICashSuper = DBFactory.SqlFactory.CreatBasciData
        eBasciData = ICashSuper.iQueryBasciData()
        UserTypeHourCost = eBasciData.FixUserHourCost
        Return UserTypeHourCost
    End Function
End Class

   这样,如果增加一个新的具体策略类的话,我们只需在B层增加一个相应的具体策略类即可。

   以上是我初步使用的策略模式,相信在后面的合作开发中,会理解更为深刻,运用也更为灵活。欢迎您的指正!

抱歉!评论已关闭.