需求:

商场收银软件,根据客户购买物品的单价和数量,计算费用,会有促销活动,打八折,满三百减一百之类的。

一,使用工厂模式。

# -*- encoding: utf-8 -*-

#现金收费抽象类
class CashSuper
def accept_cash(money)
end
end #正常收费子类
class CashNormal < CashSuper
def accept_cash(money)
money
end
end #打折收费子类
class CashRebate < CashSuper
attr_accessor :mony_rebate def initialize(mony_rebate)
@mony_rebate = mony_rebate
end def accept_cash(money)
money * mony_rebate
end
end #返利收费子类
class CashReturn < CashSuper
attr_accessor :mony_condition, :mony_return def initialize(mony_condition, mony_return)
@mony_condition = mony_condition
@mony_return = mony_return
end def accept_cash(money)
if money > mony_condition
money - (money/mony_condition) * mony_return
end
end
end #现金收费工厂类
class CashFactory
def self.create_cash_accept(type)
case type
when '正常收费'
CashNormal.new()
when '打8折'
CashRebate.new(0.8)
when '满三百减100'
CashReturn.new(300,100)
end
end
end cash0 = CashFactory.create_cash_accept('正常收费')
p cash0.accept_cash(700) cash1 = CashFactory.create_cash_accept('打8折')
p cash1.accept_cash(700) cash2 = CashFactory.create_cash_accept('满三百减100')
p cash2.accept_cash(700)

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

存在的问题:

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

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

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

二,策略模式

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得到结果。
不过,目前有一个问题,使用者需要去做判断,来选择使用哪个算法。可以和简单工场类结合。 三,策略和简单工场结合
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),也就是说封装的更彻底。 策略模式的优点

1,CashContext中封装了算法,这些算法都是完成相同的工作,只是实现不同,有助于抽取算法中的共工功能。
2,简化了单元测试,每个类可以单独测试,不互相影响。 简单的说策略模式就是用来封装算法的。
 

《大话设计模式》ruby版代码:策略模式的更多相关文章

  1. 大话设计模式C++版——抽象工厂模式

    前面说过,简单工厂模式是最基础的一种设计模式,那以工厂命名的设计模式就是23种设计模式中最多的一种,他们一脉相承,一步一步进化而来,这里就是其中的最后一种——抽象工厂模式(Abstract Facto ...

  2. 大话设计模式C++版——工厂方法模式

    工厂方法模式是以简单工厂模式为基础的,如果未了解简单工厂模式的同学可先浏览<大话设计模式C++版——简单工厂模式>.在简单工厂模式中,提到过简单工厂模式的缺陷,即违背了开发—封闭原则,其主 ...

  3. 大话设计模式C++版——简单工厂模式

    简单工厂模式应该是所有设计模式中最简单,也最基础的一种模式,以下是一个简单的采用工厂模式写一个加减法的计算器. 1.抽象接口类——依赖倒转原则(高层和底层都要依赖于抽象,针对接口编程) class I ...

  4. &lt;二&gt;读&lt;&lt;大话设计模式&gt;&gt;之策略模式

    又和大家见面了.可以坚持写出第二篇文章真不错,好好加油. <<大话设计模式>>解说策略模式是以商场收银软件程序开头的,那么问题来了.哪家商场收银软件强,开玩笑了. 读过上篇文章 ...

  5. 大话设计模式之PHP篇 - 策略模式

    什么是策略模式? 定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化. 组成:抽象策略角色: 策略类,通常由一个接口或者抽象 ...

  6. Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---策略模式之MiniDuckSimulator[转]

     1  2{<HeadFirst设计模式>之策略模式 }  3{ 本单元中的类为策略类           }  4{ 编译工具: Delphi7.0           }  5{ E- ...

  7. 大话设计模式C++版——工厂模式在COM中的典型应用

    上篇<大话设计模式C++版——抽象工厂模式>中,我们拯救世界未遂,留下小小的遗憾,本篇中我们将给出一个解决方案——COM组件技术,同时也顺便扯扯工厂模式在COM组件技术中的应用. 工厂模式 ...

  8. 大话设计模式C++版——代理模式

    本篇开始前先发个福利,程杰的<大话设计模式>一书高清电子版(带目录)已上传至CSDN,免积分下载. 下载地址:http://download.csdn.net/detail/gufeng9 ...

  9. 大话设计模式C++版——表驱动法改造简单工厂

    上回<大话设计模式C++版——简单工厂模式>中指出了简单工厂模式的缺陷,即违背了开发—封闭原则,其主要原因是由于switch的判断结构的使用,使修改或添加新的对象时需要改动简单工厂类的代码 ...

  10. JavaScript设计模式与开发实践 - 策略模式

    引言 本文摘自<JavaScript设计模式与开发实践> 在现实中,很多时候也有多种途径到达同一个目的地.比如我们要去某个地方旅游,可以根据具体的实际情况来选择出行的线路. 如果没有时间但 ...

随机推荐

  1. 剑指Offer:面试题17——合并两个排序的链表

    题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 思路1: 分别用p1,p2两个指针扫描两个有序链表,p3指针去构建新链表h3. p1.val & ...

  2. android 基础控件 EditText

    EditText 简介: EditText 控件继承 TextView ,它有TextView的所有属性和方法,并且自身是可编辑的: extends TextView java.lang.Object ...

  3. SASS使用总结

    简单用法: 变量 sass中可以定义变量,方便统一修改和维护. //sass style $fontStack: Helvetica, sans-serif; $primaryColor: #333; ...

  4. PMP考试--关于职业道德

    如果你对项目管理.系统架构有兴趣,请加微信订阅号"softjg",加入这个PM.架构师的大家庭 ★四个价值标准(value standards) 责任(responsibility ...

  5. Visual Studio 2010 C++ 工程文件解读

    在 VS2010 中,C++ 的工程文件已经和 2005 / 2008 有了很大的不同,而是完全采用 MSBUILD 的属性方式进行表达,并且可以让用户通过一次性的配置而对所有的属性进行自定义: 根据 ...

  6. jquery 设置元素内容html(),text(),val()

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. 委托delegate使用方法

    允许传递一个类A的方法m给另一个类B的对象,使得类B的对象能够调用这个方法m,说白了就是可以把方法当作参数传递. class Program { //delegate的使用方法一 public del ...

  8. 使用eclipse与jLink V8调试exynos 4412 u-boot

    /** ****************************************************************************** * @author    Maox ...

  9. JavaScript根据CSS的Media Queries来判断浏览设备的方法

    CSS 部分 首先随便新建一个用来做判断的类,然后通过 Media Queries 来对这个类的 z-index 属性赋予不同的值.这个类仅作为 JavaScript 读取使用,所以需要将其移出屏幕窗 ...

  10. ie使用firebug

    在网页插入以下代码即可. <script type="text/javascript" src="http://getfirebug.com/releases/li ...