swift设计模式学习 - 策略模式
移动端访问不佳,请访问我的个人博客
设计模式学习的demo地址,欢迎大家学习交流
策略模式
策略模式定义了算法家族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户。
策略模式的组成
- 抽象策略角色(Strategy): 策略类,通常由一个接口或者抽象类实现。
- 具体策略角色(ConcreteStrategy):包装了相关的算法和行为。
- 环境角色(Context):持有一个策略类的引用,最终给客户端调用。
策略模式的基本实现

上图是最基本的装饰模式的结构图,下面将用Swift代码来实现一个基本策略模式:
// 策略类,定义所有支持 的算法的公共接口
protocol Strategy {
func AlgorithmInterface()
}
// 具体策略类,封装了具体的算法或行为,继承于Strategy
class ConcreteStrategyA: Strategy {
func AlgorithmInterface() {
print("ConcreteStrategyA")
}
}
class ConcreteStrategyB: Strategy {
func AlgorithmInterface() {
print("ConcreteStrategyB")
}
}
class ConcreteStrategyC: Strategy {
func AlgorithmInterface() {
print("ConcreteStrategyC")
}
}
// Context上下文,用一个 ConcreteStrategy来配置,维护一个对Strategy对象的引用
class Context {
var strategy: Strategy?
func ContextInterface() {
strategy?.AlgorithmInterface()
}
}
以上代码是最简单的策略模式的实现过程,定义了一个Strategy的算法族,通过它的子类可以实现算法(AlgorithmInterface)的替换,而不会影响到客户端。
用策略模式解决实际问题(商场打折)
我们知道在商场中一般有很多打折优惠方案,类似这种问题就可以用策略模式来解决,打折不同的方案就相当于不同的策略(ConcreteStrategy),然后用一个Context类来实现不同算法的切换,下面是商场打折策略模式的实现于UML图:

以上是一个简单的商场收银系统,CashNormal为普通收费子类,CashRebate为打折收费子类,CashReturn为返利收费子类,下面是代码的实现过程:
import Foundation
// 定义一个收费的策略接口
protocol CashSuper {
func acceptCash(money: Double) -> Double
}
// 普通收费子类
class CashNormal: CashSuper {
// 正常原价返回
func acceptCash(money: Double) -> Double {
return money
}
}
// 打折收费子类
class CashRebate: CashSuper {
// 折扣率
private var moneyRebate: Double = 1.0
init(moneyRebate: Double) {
self.moneyRebate = moneyRebate
}
func acceptCash(money: Double) -> Double {
return money*moneyRebate
}
}
// 返利收费子类
class CashReturn: CashSuper {
// 返利要求
private var moneyCondition: Double = 0
// 返多少
private var moneyReturn: Double = 0
init(moneyCondition: Double, moneyReturn: Double) {
self.moneyCondition = moneyCondition
self.moneyReturn = moneyReturn
}
func acceptCash(money: Double) -> Double {
var result = money
if money >= moneyCondition {
result = money - floor(money / moneyCondition) * moneyReturn
}
return result
}
}
// context类
class CashContext {
private var cs: CashSuper?
// 通过枚举判断使用哪种方式
init(style: CashStyle) {
switch style {
case .normal:
cs = CashNormal()
case .rebate(moneyRebate: let money):
cs = CashRebate(moneyRebate: money)
case .return(moneyCondition: let moneyCondition, moneyReturn: let moneyReturn):
cs = CashReturn(moneyCondition: moneyCondition, moneyReturn: moneyReturn)
}
}
func getResult(money: Double) -> Double {
return cs?.acceptCash(money: money) ?? 0
}
}
// 优惠的枚举类型
enum CashStyle {
case normal
case rebate(moneyRebate: Double)
case `return`(moneyCondition: Double, moneyReturn: Double)
}
下面我们测试一下代码:
let money: Double = 300
// 普通
let normal = CashContext(style: .normal)
// 打7折
let rebate = CashContext(style: .rebate(moneyRebate: 0.7))
// 满一百返20
let `return` = CashContext(style: .return(moneyCondition: 100, moneyReturn: 20))
print("普通: \(normal.getResult(money: money))")
print("打7折: \(rebate.getResult(money: money))")
print("满一百返20: \(`return`.getResult(money: money))")
下面是执行的结果:
普通: 300.0
打7折: 210.0
满一百返20: 240.0
策略模式总结
我们可以理解为策略就是用来封装算法,但在实践过程中不用那么死板,可以用来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。
以上是我对于策略模式的理解,如果有不对的地方欢迎大家交流,最后谢谢大家的阅读~~
swift设计模式学习 - 策略模式的更多相关文章
- swift设计模式学习 - 代理模式
移动端访问不佳,请访问我的个人博客 设计模式学习的demo地址,欢迎大家学习交流 代理模式 代理模式为其他对象提供一种代理以控制对这个对象的访问,在某些情况下,一个对象不适合或者不能直接引用另一个对象 ...
- swift设计模式学习 - 原型模式
移动端访问不佳,请访问我的个人博客 设计模式学习的demo地址,欢迎大家学习交流 原型模式 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 定义 用原型实例指定创建对象的种类,并且通 ...
- 设计模式学习——策略模式(Strategy Pattern)
0. 前言 最近在重构公司的一个项目的时候,在抽取DES加密重复部分代码的时候,突然间想起了策略模式,感觉策略模式好像可以应用上,于是重新学习了下策略模式.注:在DES加密中,有DES和TDES算法, ...
- swift设计模式学习 - 模板方法模式
移动端访问不佳,请访问我的个人博客 设计模式学习的demo地址,欢迎大家学习交流 模板方法模式 模板方法模式,定义一个操作中算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结 ...
- JavaScript设计模式之策略模式(学习笔记)
在网上搜索“为什么MVC不是一种设计模式呢?”其中有解答:MVC其实是三个经典设计模式的演变:观察者模式(Observer).策略模式(Strategy).组合模式(Composite).所以我今天选 ...
- 设计模式学习--复合模式(Compound Pattern)
设计模式学习--复合模式(Compound Pattern) 概述 ——————————————————————————————————————————————————— 2013年8月4日<H ...
- [design-patterns]设计模式之一策略模式
设计模式 从今天开始开启设计模式专栏,我会系统的分析和总结每一个设计模式以及应用场景.那么首先,什么是设计模式呢,作为一个软件开发人员,程序人人都会写,但是写出一款逻辑清晰,扩展性强,可维护的程序就不 ...
- 设计模式之策略模式和状态模式(strategy pattern & state pattern)
本文来讲解一下两个结构比较相似的行为设计模式:策略模式和状态模式.两者单独的理解和学习都是比较直观简单的,但是实际使用的时候却并不好实践,算是易学难用的设计模式吧.这也是把两者放在一起介绍的原因,经过 ...
- 设计模式:策略模式(Strategy)
定 义:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化, 不会影响到使用算法的客户. 示例:商场收银系统,实现正常收费.满300返100.打8折.......等不同收费 ...
随机推荐
- qt——常用的布局方法
布局相关对象及简介 窗体上的所有的控件必须有一个合适的尺寸和位置.Qt提供了一些类负责排列窗体上的控件,主要有:QHBoxLayout,QVBoxLayout,QGridLayout,QStackLa ...
- 【Python】百度贴吧-中国好声音评论爬爬【自练OK-csv提取格式及评论提取空格等问题待改进】
代码编写思路: 学习知识点: 1.class=a b(a假设是字体-宋体,b是颜色-蓝色:class中可以同时有两个参数a,b(宋体+蓝色),两者用空格隔开即可) 2.拓展1:想要soup到某个元素, ...
- 梯度下降算法(Gradient Descent)
近期在搞论文,须要用梯度下降算法求解,所以又一次整理分享在这里. 主要包含梯度介绍.公式求导.学习速率选择.代码实现. 梯度下降的性质: 1.求得的解和选取的初始点有关 2.能够保证找到局部最优解,由 ...
- 在系统启动时,Windows Vista 中、 在 Windows 7 中,Windows Server 2008 中和在 Windows Server 2008 R2 中的 497 天后未关闭 TIME_WAIT 状态的所有 TCP/IP 端口
在系统启动时,Windows Vista 中. 在 Windows 7 中,Windows Server 2008 中和在 Windows Server 2008 R2 中的 497 天后未关闭 TI ...
- .NET数据挖掘与机器学习开源框架
1. 数据挖掘与机器学习开源框架 1.1 框架概述 1.1.1 AForge.NET AForge.NET是一个专门为开发者和研究者基于C#框架设计的,他包括计算机视觉与人工智能,图像处理,神经 ...
- 十天精通CSS3(7)
:enabled选择器 在Web的表单中,有些表单元素有可用(“:enabled”)和不可用(“:disabled”)状态,比如输入框,密码框,复选框等.在默认情况之下,这些表单元素都处在可用状态.那 ...
- [py][mx]django邮箱注册的验证码部分-django-simple-captcha库使用
邮箱注册-验证码 验证码使用第三方库django-simple-captcha 这个安装图形插件步骤官网有哦 - 1.Install django-simple-captcha via pip: pi ...
- 实习培训——Servlet(6)
实习培训——Servlet(6) 1 Servlet 客户端 HTTP 请求 当浏览器请求网页时,它会向 Web 服务器发送特定信息,这些信息不能被直接读取,因为这些信息是作为 HTTP 请求的头的 ...
- CentOS忘记普通用户密码解决办法
普通用户忘记密码 1.使用root用户登录系统,找到/etc/shadow文件. 2.找到用户名开头的那一行,例如我的用户名为pds,,以冒号为分割符,红色部分是密码加密部分 pds:$1$Civop ...
- <span> 标签
<span> 标签被用来组合文档中的行内元素. 如果不对 span 应用样式,那么 span 元素中的文本 与 其他文本不会有任何视觉上的差异.尽管如此,上例中的 span 元素仍然为 p ...