每日一个设计模式(三)——命令模式

引子

今天,我们来讨论命令模式(英语:Command pattern),这个模式可能不那么常见,但是在应用软件上使用比较广泛。

理论

先看维基百科上对命令模式的定义:

面向对象编程的范畴中,命令模式(英语:Command pattern)是一种设计模式,它尝试以对象来代表实际行动。命令对象可以把行动(action) 及其参数封装起来,于是这些行动可以被:

  • 重复多次
  • 取消(如果该对象有实现的话)
  • 取消后又再重做

代码实现

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
49
50
51
52
const Command = (function () {
let cmds = [];
let recever;
return {
bind: function (obj) {
recever = obj;
},

exec: function (cmd) {
cmds.push(cmd);
recever[cmd.type] && recever[cmd.type](cmd.payload);
},

undo: function () {
let cmd = cmds.pop();
if (!cmd) return;
recever[cmd.type] && recever[cmd.type](cmd.payload);
},
};
})();

let operation = {
find: function () {
console.log("find something");
},
hello: function (payload) {
console.log("hello " + payload);
},
delete: function (payload) {
console.log("delete " + payload);
},
};

Command.bind(operation);

Command.exec({
type: "find",
}); //"find something"

Command.exec({
type: "hello",
payload: "bert",
}); //"hello bert"

Command.exec({
type: "delete",
payload: "file1",
}); // "delete file1"

Command.undo(); // "delete file1"

Command.undo(); // "hello bert"

上面这段代码我们模拟一个命令执行器,让它绑定一个用户草走对象,执行一系列操作,当用户撤销操作时,按栈的方式执行操作(这里简便起见没有写撤销操作函数,只是原地执行旧的函数)。

前端中的应用

我们在做一些 web 软件时,可以考虑使用命令模式的思想,一个常见的例子就是富文本编辑器,无论是对文本内容的编辑撤销,又或是流程图的拖动回退等等,这些操作都可以抽象成命令模式的方式,保存用户对页面 DOM 的操作,撤销时对这些操作进行回退。

总结

命令模式适合对重复多次、具有可撤销行为的行动对象使用。

参考文献

命令模式

作者

bert_cai

发布于

2019-04-30

更新于

2020-11-16

许可协议

评论