今天遇到这样一个问题,我现在有一个整数数组,如:

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)实现的更多相关文章

  1. 设计模式 - 命令模式(command pattern) 多命令 具体解释

    命令模式(command pattern) 多命令 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考命令模式: http://blog.csdn.ne ...

  2. 设计模式 - 命令模式(command pattern) 具体解释

    命令模式(command pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 命令模式(command pattern) : 将请求封装成对 ...

  3. 设计模式 - 命令模式(command pattern) 宏命令(macro command) 具体解释

    命令模式(command pattern) 宏命令(macro command) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考: 命名模式(撤销) ...

  4. 乐在其中设计模式(C#) - 命令模式(Command Pattern)

    原文:乐在其中设计模式(C#) - 命令模式(Command Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 命令模式(Command Pattern) 作者:webabcd ...

  5. 设计模式 - 命令模式(command pattern) 撤销(undo) 具体解释

    命令模式(command pattern) 撤销(undo) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 參考命令模式: http://blog.cs ...

  6. 二十四种设计模式:命令模式(Command Pattern)

    命令模式(Command Pattern) 介绍将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可取消的操作. 示例有一个Message实体类,某个 ...

  7. 设计模式-15命令模式(Command Pattern)

    1.模式动机 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使 ...

  8. 设计模式(六):控制台中的“命令模式”(Command Pattern)

    今天的博客中就来系统的整理一下“命令模式”.说到命令模式,我就想起了控制台(Console)中的命令.无论是Windows操作系统(cmd.exe)还是Linux操作系统(命令行式shell(Comm ...

  9. 十一个行为模式之命令模式(Command Pattern)

    定义: 将一个请求封装成对象,使得请求发送者和请求接受者之间相互隔离,消除两者之间的耦合.引入命令类,使得不同请求对客户参数化,并且可以对命令添加附件操作,如:排队.撤销.日志.组合等. 结构图: C ...

随机推荐

  1. Django入门1

    Django中的应用是以APP形式存在的,这是Django的主要特色. 入门--Hello,Django     在mysite中新建文件views.py,并在里面定义方法hello: 这里#-*- ...

  2. IOS网络第二天 - 07-发送JSON给服务器

    *************** #import "HMViewController.h" #import "MBProgressHUD+MJ.h" @inter ...

  3. 如何给你的LinuxVPS装个远程桌面

    有些人抱怨Linux的系统没有桌面,用着实在是不方便.今天整理一下网上的教程,给VPS装个桌面环境.Centos系统+X Window+GNOME Desktop. 此程序会安装无数乱七八糟的东西到你 ...

  4. __DATE__ 与 __TIME__转换为标准格式时间字符串的方法

    // Example of __DATE__ string: "Jul 27 2012"// 01234567890 #define BUILD_YEAR_CH0 (__DATE_ ...

  5. Unity字节序问题

    问题 Unity中有些配置信息并不想在发布之后给其他人看到,所以在打包的时候进行了简单的编码处理,然后保存为.bytes类型,读取的时候再进行解码处理.今天遇到的很奇葩的问题是: 如果bytes文件U ...

  6. centos6修改nameserver

    1.直接修改/etc/resolv.conf,重启网卡 #service network restart 后发现并没有修改掉 2.直接修改ifcfg-eth0文件 /etc/sysconfig/net ...

  7. SMTP Error: Could not connect to SMTP host

    PHPMailer是一个非常棒的开源邮件类,使用也非常简单,但是对于虚拟主机来说,往往要受到各种限制.刚才我在虚拟主机上使用PHPMailer就遇到一个“SMTP Error: Could not c ...

  8. Maven的依赖和传递性质

    1. 引入项目所需jar包 Maven项目直白的一大特点就是一般情况下不需要去自行下载jar包以及目标jar包的依赖包并导入,只需要在去Maven的中央仓库http://mvnrepository.c ...

  9. CSS中定位和浮动对行内元素的宽高的影响

    行内元素的大小是由元素里面的内容撑开的宽高决定的,就算在css中对行内元素设置width,height.行内元素也会忽略宽高的设置. 但是当行内元素使用position:absolute或者posit ...

  10. Oracle之ORDER BY

    ------------基本查询--1.查询出的是一张虚拟的结果表-----基本语法---- * 所有列(字段)select * from emps; -----查询指定字段select employ ...