Swift语言之命令模式(Command Pattern)实现
今天遇到这样一个问题,我现在有一个整数数组,如:
var numbers = [3, 7, 12, 9, 200]
现需要对其中的每一个数字都执行一系列相同的加减乘除操作,如对每一个数字都加5乘8再减去1,但是这样的操作在编译时并不确定,需要在运行时由用户指定;
一看到这个题目,当然就想到了用设计模式中的命令模式来实现;
于是先写了这样的一个类:
class Calculator {
private(set) var total = 0
required init(value: Int){
total = value
}
func add(amount: Int) {
total += amount
}
func substract(amount: Int) {
total -= amount
}
func multiply(amount: Int) {
total = total * amount
}
func divide(amount: Int) {
total = total / amount
}
}
这个类用于实现对某个数执行不同的操作。
下一步中我创建了一个Command类,用于记录需要执行的操作:
struct Command {
typealias OperationType = (Calculator -> Int -> Void)
let operation: OperationType
let amount: Int
init(operation: OperationType, amount: Int) {
self.operation = operation
self.amount = amount
}
func execute(calculator: Calculator) {
operation(calculator)(amount)
}
}
在该类中我定义了一个名为OperationType的类型别名,从定义中可以看出,OperationType类型的实例是一个Closure,该Closure接受一个Calculator类型的实例,并返回一个类型为Int -> Void的Closure(此Closure的类型就是Calculator中每个方法的类型);
amount为执行那个操作的参数值;
待一切完毕后,由用户来指定要执行的命令,如将数组numbers中的每一个值加5乘8再减去1,则可以这样实现:
var commands = [Command]()
commands.append(Command(operation: Calculator.add, amount: 5))
commands.append(Command(operation: Calculator.multiply, amount: 8))
commands.append(Command(operation: Calculator.substract, amount: 1))
这样做并没有达到Command设计模式想要达到的目的,及实现命令的发出者与命令的执行者之间的脱耦;于是我加入了一个新的enum类型:
enum OperationType {
case Add(Int)
case Substract(Int)
case Multiply(Int)
case Divide(Int)
}
这个enum类型中的每一个成员都自带一个关联值,及要执行操作的参数,于是Command类型可以改变为:
struct Command {
let operationType: OperationType
init(operationType: OperationType) {
self.operationType = operationType
}
func execute(calculator: Calculator) {
switch self.operationType {
case .Add(let value):
calculator.add(value)
case .Substract(let value):
calculator.substract(value)
case .Multiply(let value):
calculator.multiply(value)
case .Divide(let value):
calculator.divide(value)
}
}
}
重新创建Commands数组:
var commands = [Command]()
commands.append(Command(operationType: .Add(5)))
commands.append(Command(operationType: .Multiply(8)))
commands.append(Command(operationType: .Substract(1)))
OK,执行所有命令:
for number in numbers {
var calculator = Calculator(value: number)
for command in commands {
command.execute(calculator)
}
println("\(number) -> \(calculator.total)")
}
这里是结果:

Swift语言之命令模式(Command Pattern)实现的更多相关文章
- 设计模式 - 命令模式(command pattern) 多命令 具体解释
命令模式(command pattern) 多命令 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考命令模式: http://blog.csdn.ne ...
- 设计模式 - 命令模式(command pattern) 具体解释
命令模式(command pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 命令模式(command pattern) : 将请求封装成对 ...
- 设计模式 - 命令模式(command pattern) 宏命令(macro command) 具体解释
命令模式(command pattern) 宏命令(macro command) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考: 命名模式(撤销) ...
- 乐在其中设计模式(C#) - 命令模式(Command Pattern)
原文:乐在其中设计模式(C#) - 命令模式(Command Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 命令模式(Command Pattern) 作者:webabcd ...
- 设计模式 - 命令模式(command pattern) 撤销(undo) 具体解释
命令模式(command pattern) 撤销(undo) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 參考命令模式: http://blog.cs ...
- 二十四种设计模式:命令模式(Command Pattern)
命令模式(Command Pattern) 介绍将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可取消的操作. 示例有一个Message实体类,某个 ...
- 设计模式-15命令模式(Command Pattern)
1.模式动机 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使 ...
- 设计模式(六):控制台中的“命令模式”(Command Pattern)
今天的博客中就来系统的整理一下“命令模式”.说到命令模式,我就想起了控制台(Console)中的命令.无论是Windows操作系统(cmd.exe)还是Linux操作系统(命令行式shell(Comm ...
- 十一个行为模式之命令模式(Command Pattern)
定义: 将一个请求封装成对象,使得请求发送者和请求接受者之间相互隔离,消除两者之间的耦合.引入命令类,使得不同请求对客户参数化,并且可以对命令添加附件操作,如:排队.撤销.日志.组合等. 结构图: C ...
随机推荐
- WPF整理-XAML访问静态属性
"XAML provides an easy way to set values of properties—type converters and the extended propert ...
- C 格式输出
1 一般格式 printf(格式控制,输出表列) 例如:printf("i=%d,ch=%c\n",i,ch); 说明: (1) “格式控制”是用双撇号括起 ...
- 自动爬取ZiMuZu的内容发布到Wordpress
先说一下大致的步骤. 首先需要模拟浏览器登录网站才能看到相应电影信息, 然后通过正则表达式从网页源代码中筛选出所需要的电影, 最后通过python-wordpress-xmlrpc将信息逐条发布到Wo ...
- html css 样式继承的问题
body 设置css中可以继承的属性:letter-spacing.word-spacing.white-space.line-height.color.font等 但有时,body的样式,不能在有的 ...
- Myeclipse java程序中运行图片无法加载并且乱码
Windows---prefrence--workspace--text file encoding亲测有效
- ESXi 5.5开启并配置SNMP
1. 安装vshpere cli 2.设定SNMP通讯字并开启SNMP功能 进入到bin目录. C:\Program Files (x86)\VMware\VMware vSphere CLI\bin ...
- WordPress基础:订阅源rss的使用
设置->阅读,可设置rss显示效果 RSS源为:http://wordpress目录/feed 把这个地址放入你的rss阅读器进行订阅即可,最简单的就是使用QQ邮箱里面的阅读空间进行订阅.
- vue-router 创建 vue 单页应用示例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Hadoop - Unable to load native-hadoop library for your platform
简介 运行hadoop或者spark(调用hdfs等)时,总出现这样的错误“Unable to load native-hadoop library for your platform”,其实是无法加 ...
- 解决界面有搜索栏时,点击TableView的空白界面,键盘不消失的问题
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(h ...