Farlanki

命令模式

字数统计: 457阅读时长: 2 min
2015/11/24 Share

命令模式

简介

命令模式提供了一个对被调用方法的详情进行封装,以达到推迟调用或者可供不同元素调用的机制.使用命令模式的优点是1.可以执行撤销操作2.可以创造宏.

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
protocol Command {
func execute();
}
class GenericCommand<T> : Command {
private var receiver: T;
private var instructions: T -> Void;
init(receiver:T, instructions: T -> Void) {
self.receiver = receiver; self.instructions = instructions;
}
func execute() {
instructions(receiver);
}
class func createCommand(receiver:T, instuctions: T -> Void) -> Command {
return GenericCommand(receiver: receiver, instructions: instuctions);
} }


class Calculator {
private(set) var total = 0; private var history = [Command]();
func add(amount:Int) {
addUndoCommand(Calculator.subtract, amount: amount);
total += amount;
}
func subtract(amount:Int) {
addUndoCommand(Calculator.add, amount: amount);
total -= amount;
}
func multiply(amount:Int) {
addUndoCommand(Calculator.divide, amount: amount);
total = total * amount;
}
func divide(amount:Int) {
addUndoCommand(Calculator.multiply, amount: amount);
total = total / amount;
}

private func addUndoCommand(method:Calculator -> Int -> Void, amount:Int) {
self.history.append(GenericCommand<Calculator>.createCommand(self,
instuctions: {calc in
method(calc)(amount);
})); }
func undo() {
if self.history.count > 0 {
self.history.removeLast().execute();
// temporary measure - executing the command adds to the history
self.history.removeLast();
} }
}

这是在swift上的实现方法.

  • 在代码中出现了一个这样的参数:method:Calculator -> Int -> Void.注意,这是在swift中实例方法作为参数的写法.通常,swift类中调用实例方法的写法是:
1
2
3
4
...
let printerObject = printer()
printerObject.printMessage("hello")
...

但是,一种替代的写法是:

1
2
3
4
...
let printerObject = printer()
printer.printMessage(printerObject)("hello")
...

所以,method:Calculator -> Int -> Void实际上是Calculator的实例对象中加减乘除方法的类型.

  • 在使用calcluator的每一个操作前,创建一个command对象并且添加到history中.创建command对象时,需要两个参数,分别为receiverinstruction.receiver作为实例方法的第二种写法的第一个参数.instruction是一个block,使用了block的值捕获特性取得了methodamount.
CATALOG
  1. 1. 命令模式
    1. 1.1. 简介
    2. 1.2. 实现