《大话设计模式》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设计模式与开发实践> 在现实中,很多时候也有多种途径到达同一个目的地.比如我们要去某个地方旅游,可以根据具体的实际情况来选择出行的线路. 如果没有时间但 ...
随机推荐
- 使用 Cocos2d-x 3.1.1 创建 Windows Phone 8 游戏开发环境
cocos2d-x 是目前流行的游戏游戏开发框架,目前最新的版本是 3.1.1, 网上有些教程已经比较老了,本文将会介绍如何使用最新的 3.1.1 创建 Windows Phone 8 开发环境. 本 ...
- 初探接口测试框架--python系列4
点击标题下「蓝色微信名」可快速关注 坚持的是分享,搬运的是知识,图的是大家的进步,没有收费的培训,没有虚度的吹水,喜欢就关注.转发(免费帮助更多伙伴)等来交流,想了解的知识请留言,给你带来更多价值,是 ...
- 【caffe-windows】 caffe-master 之Matlab中model的分类应用
此篇讲述在matlab中,如何将训练好的model用于图像分类.将以mnist为例,主要用到caffe-master\matlab\demo 下的classification_demo.m ,可参考我 ...
- Android开发-API指南-Content Provider
Content Providers 英文原文:http://developer.android.com/guide/topics/providers/content-providers.html 采集 ...
- 【LeetCode】7. Reverse Integer 整型数反转
题目: Reverse digits of an integer. Example1: x = 123, return 321 Example2: x = -123, return -321 思路:不 ...
- 【测试】在hr用户下自行创建T1和T2表写一条SQL语句,(NL连接)
SQL> select t1.* from t1,t2 where t1.object_id=t2.object_id; rows selected. Execution Plan ------ ...
- JS实现联想输入(一)
这里是我们的项目中的一个使用JS实现联想输入的功能代码,在此做个小的记录并且将它分享给大家希望对园中的朋友有用! 我将分享三段都非常简单的代码,仅仅作为个人的一点小小的积累而已! 1:后台的Actio ...
- 学习练习 java 集合
将1—100之间的所有正整数存放在一个List集合中,并将集合中索引位置是10的对象从集合中移除 package com.hanqi; import java.util.*; public class ...
- Leetcode008. String to Integer (atoi)
/* improvement on dealing with overflow accroding to this: * https://discuss.leetcode.com/topic/5745 ...
- Struts2使用ModelDriven后JSON数据返回不正确
在struts.xml中加入<param name="root">action</param> <result name="exist&qu ...