设计模式之命令模式

2019-01-31

命令模式定义

命令模式将一个请求或者行为封装成一个对象。可以在对象之间被传递,存储,修改,撤销。

命令模式使用场景

  • 需要实现撤销与恢复功能
  • 记录请求日志,在需要撤销操作的时候可以使用
  • 想实现一个对象参数化一个动作以执行操作,并且用不同的命令对象替换回调函数

命令模式中的角色

  • 接收者:负责具体的功能实现
  • 命令协议:定义一些命令方法
  • 命令对象:负责调用接收者的逻辑方法
  • 命令管理者:负责命令对象之间的调度

代码实现

接收者

1
2
3
class Receiver {
var soundNum: Int = 10
}

命令协议

1
2
3
4
protocol CommandProtocol {
func excuteCommand() -> Void
func undoCommand() -> Void
}

命令对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class SoundUpCommand: CommandProtocol {
var receiver: Receiver?
init(receiver: Receiver) {
self.receiver = receiver
}
func excuteCommand() {
self.receiver?.soundNum += 1
}
func undoCommand() {
self.receiver?.soundNum -= 1
}
}
class SoundDownCommand: CommandProtocol {
var receiver: Receiver?
init(receiver: Receiver) {
self.receiver = receiver
}
func excuteCommand() {
self.receiver?.soundNum -= 1
}
func undoCommand() {
self.receiver?.soundNum += 1
}
}

命令管理者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class CommandManager {
var commands: [(CommandProtocol)] = []
var comand: CommandProtocol?
func setCommand(cmd: CommandProtocol) -> Void {
self.comand = cmd
}
func executeCmd() -> Void {
if let cmd = self.comand {
cmd.excuteCommand()
self.commands.append(cmd)
}
}
func updoCmd() -> Void {
if !self.commands.isEmpty {
let cmd = self.commands.last!
cmd.undoCommand()
self.commands.removeLast()
}
}
}

终端调用

1
2
3
4
5
6
7
8
let receiver = Receiver()
let upcmd = SoundUpCommand(receiver: receiver)
let manager = CommandManager()
manager.setCommand(cmd: upcmd)
manager.executeCmd()
print(receiver.soundNum)//11
manager.updoCmd()
print(receiver.soundNum)//10