《大话设计模式》ruby版代码:策略模式
需求:
商场收银软件,根据客户购买物品的单价和数量,计算费用,会有促销活动,打八折,满三百减一百之类的。
一,使用工厂模式。
# -*- 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版代码:策略模式的更多相关文章
- 大话设计模式C++版——抽象工厂模式
前面说过,简单工厂模式是最基础的一种设计模式,那以工厂命名的设计模式就是23种设计模式中最多的一种,他们一脉相承,一步一步进化而来,这里就是其中的最后一种——抽象工厂模式(Abstract Facto ...
- 大话设计模式C++版——工厂方法模式
工厂方法模式是以简单工厂模式为基础的,如果未了解简单工厂模式的同学可先浏览<大话设计模式C++版——简单工厂模式>.在简单工厂模式中,提到过简单工厂模式的缺陷,即违背了开发—封闭原则,其主 ...
- 大话设计模式C++版——简单工厂模式
简单工厂模式应该是所有设计模式中最简单,也最基础的一种模式,以下是一个简单的采用工厂模式写一个加减法的计算器. 1.抽象接口类——依赖倒转原则(高层和底层都要依赖于抽象,针对接口编程) class I ...
- <二>读<<大话设计模式>>之策略模式
又和大家见面了.可以坚持写出第二篇文章真不错,好好加油. <<大话设计模式>>解说策略模式是以商场收银软件程序开头的,那么问题来了.哪家商场收银软件强,开玩笑了. 读过上篇文章 ...
- 大话设计模式之PHP篇 - 策略模式
什么是策略模式? 定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化. 组成:抽象策略角色: 策略类,通常由一个接口或者抽象 ...
- Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---策略模式之MiniDuckSimulator[转]
1 2{<HeadFirst设计模式>之策略模式 } 3{ 本单元中的类为策略类 } 4{ 编译工具: Delphi7.0 } 5{ E- ...
- 大话设计模式C++版——工厂模式在COM中的典型应用
上篇<大话设计模式C++版——抽象工厂模式>中,我们拯救世界未遂,留下小小的遗憾,本篇中我们将给出一个解决方案——COM组件技术,同时也顺便扯扯工厂模式在COM组件技术中的应用. 工厂模式 ...
- 大话设计模式C++版——代理模式
本篇开始前先发个福利,程杰的<大话设计模式>一书高清电子版(带目录)已上传至CSDN,免积分下载. 下载地址:http://download.csdn.net/detail/gufeng9 ...
- 大话设计模式C++版——表驱动法改造简单工厂
上回<大话设计模式C++版——简单工厂模式>中指出了简单工厂模式的缺陷,即违背了开发—封闭原则,其主要原因是由于switch的判断结构的使用,使修改或添加新的对象时需要改动简单工厂类的代码 ...
- JavaScript设计模式与开发实践 - 策略模式
引言 本文摘自<JavaScript设计模式与开发实践> 在现实中,很多时候也有多种途径到达同一个目的地.比如我们要去某个地方旅游,可以根据具体的实际情况来选择出行的线路. 如果没有时间但 ...
随机推荐
- 海外支付:遍布全球的Paypal
海外支付:遍布全球的Paypal 吴剑 2015-11-26 原创文章,转载必需注明出处:http://www.cnblogs.com/wu-jian 吴剑 http://www.cnblogs.co ...
- Android WebView Long Press长按保存图片到手机
<span style="font-size:18px;">首先要先注册长按监听菜单 private String imgurl = ""; /** ...
- 慕课网-安卓工程师初养成-3-8 Java中的条件运算符
来源:http://www.imooc.com/code/1306 条件运算符( ? : )也称为 “三元运算符”. 语法形式:布尔表达式 ? 表达式1 :表达式2 运算过程:如果布尔表达式的值为 t ...
- 学习总结 JAVA环境配置 及其相应的步骤
相应的操作步骤 第一步: 右键我的电脑→属性→高级系统设置→环境变量→打开环境变量 第二步:在系统变量中添加JAVA_HOME ,并引用到相对应的地址. 第三步:在系统变量 path 中最前端(按ho ...
- 洛谷P1457 城堡 The Castle
P1457 城堡 The Castle 137通过 279提交 题目提供者该用户不存在 标签USACO 难度提高+/省选- 提交 讨论 题解 最新讨论 暂时没有讨论 题目描述 我们憨厚的USACO ...
- 用Scrapy爬虫下载图片(豆瓣电影图片)
用Scrapy爬虫的安装和入门教程,这里有,这篇链接的博客也是我这篇博客的基础. 其实我完全可以直接在上面那篇博客中的代码中直接加入我要下载图片的部分代码的,但是由于上述博客中的代码已运行,已爬到快九 ...
- 拿搬东西来解释udp tcpip bio nio aio aio异步
[群主]雷欧纳德简单理解 tcpip是有通信确认的面对面通信 有打招呼的过程 有建立通道的过程 有保持通道的确认 有具体传输udp是看到对面的人好像在对面等你 就往对面扔东西[群主]雷欧 ...
- 你真的理解z-index吗?
一.前言 假如只是开发简单的弹窗效果,懂得通过z-index来调整元素间的层叠关系就够了.但要将多个弹窗间层叠关系给处理好,那么充分理解z-index背后的原理及兼容性问题就是必要的知识储备了.本文作 ...
- Promise机制
Promise的诞生与Javascript中异步编程息息相关,js中异步编程主要指的是setTimout/setInterval.DOM事件机制.ajax,通过传入回调函数实现控制反转.异步编程为js ...
- Android IOS WebRTC 音视频开发总结(六)-- iOS开发之含泪经验
前段时间在搞webrtc iOS开发,所以将标题改为了Android IOS WebRTC 音视频开发总结, 下面都是开发过程中的经验总结,转载请说明出处(博客园RTC.Blacker): 1. IO ...