实例解析Ruby设计模式编程中Strategy策略模式的使用

2019-09-25 09:38:38刘景俊

做到了自定义折扣比例和满减的数量。

存在的问题:

增加活动的种类时,打五折,满五百减二百,需要在工厂类中添加分支结构。

活动是多种多样的,也有可能增加积分活动,满100加10积分,积分一定可以领取活动奖品,这时就要增加一个子类。

但是每次增加活动的时候,都要去修改工厂类,是很糟糕的处理方式,面对算法有改动时,应该有更好的办法。

2.策略模式

CashSuper和子类都是不变的,增加以下内容:

class CashContext
  
  attr_accessor :cs
  
  def initialize(c_super)
    @cs = c_super
  end
  
  def result(money)
    cs.accept_cash(money)
  end

end

type = '打8折'
cs=case type
  when '正常收费'
    CashContext.new(CashNormal.new())
  when '打8折'
    CashContext.new(CashRebate.new(0.8))
  when '满三百减100'
    CashContext.new(CashReturn.new(300,100))
  end
p cs.result(700)

CashContext类对不同的CashSuper子类进行了封装,会返回对应的result。也就是对不同的算法进行了封装,无论算法如何变化。都可以使用result得到结果。
不过,目前有一个问题,使用者需要去做判断,来选择使用哪个算法。可以和简单工场类结合。

3.策略和简单工场结合

class CashContext
  
  attr_accessor :cs
  
  def initialize(type)
    case type
    when '正常收费'
      @cs = CashNormal.new()
    when '打8折'
      @cs = CashRebate.new(0.8)
    when '满三百减100'
      @cs = CashReturn.new(300,100)
    end
  end
  
  def result(money)
    cs.accept_cash(money)
  end

end

cs=CashContext.new('打8折')

p cs.result(700)

CashContext中实例化了不同的子类。(简单工厂)
将子类选择的过程转移到了内部,封装了算法(策略模式)。

调用者使用更简单,传入参数(活动类型,原价),即可得到最终的结果。
这里使用者只需要知道一个类(CashContext)就可以了,而简单工场需要知道两个类(CashFactory的accept_cash方法和CashFactory),也就是说封装的更彻底。