Skip to content

Commit b33e6d7

Browse files
committed
命令模式
1 parent 5d1af68 commit b33e6d7

File tree

1 file changed

+169
-0
lines changed

1 file changed

+169
-0
lines changed

nine-chapter/command.js

+169
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
// 有时候需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请 求的操作是什么,
2+
// 此时希望用一种松耦合的方式来设计软件,使得请求发送者和请求接 收者能够消除彼此之间的耦合关系
3+
4+
/*
5+
按钮的绘制
6+
<body>
7+
<button id='button1'> 点击按钮1 </button>
8+
<button id='button2'> 点击按钮2 </button>
9+
<button id='button3'> 点击按钮3 </button>
10+
</body>
11+
12+
<script>
13+
var button1 = document.getElementById('button1')
14+
var button2 = document.getElementById('button2')
15+
var button3 = document.getElementById('button3')
16+
</script>
17+
*/
18+
19+
//setCommand 函数负责往按钮上面安装命令
20+
21+
var setCommand = function (button,command) {
22+
button.onclick = function(){
23+
command.execute();
24+
}
25+
}
26+
27+
//点击按钮的之后具体行为是另一个程序员操作
28+
var MenuBar = {
29+
refresh:function(){
30+
console.log('刷新菜单目录')
31+
}
32+
}
33+
34+
var SubMenu = {
35+
add:function(){
36+
console.log('增加子菜单')
37+
},
38+
del:function(){
39+
console.log('删除子菜单')
40+
}
41+
}
42+
43+
//把行为都封装在命令类中
44+
var RefreshMenuCommand = function(receiver){
45+
this.receiver = receiver;
46+
}
47+
48+
RefreshMenuCommand.prototype.execute = function(){
49+
this.receiver.refresh();
50+
}
51+
52+
var AddSubMenuCommand = function(receiver){
53+
this.receiver = receiver;
54+
}
55+
AddSubMenuCommand.prototype.execute = function(){
56+
this.receiver.add();
57+
}
58+
59+
var DelSubMenuCommand = function(receiver){
60+
this.receiver = receiver
61+
}
62+
63+
DelSubMenuCommand.prototype.execute = function(){
64+
console.log('删除子菜单')
65+
}
66+
67+
// 最后就是把命令接收者传入到 command 对象中,并且把 command 对象安装到 button 上面
68+
var refreshMenuCommand = new RefreshMenuCommand(MenuBar);
69+
var adddSunMenuCommand = new AddSubMenuCommand(SubMenu);
70+
var delSubMenuCommand = new DelSubMenuCommand(SubMenu);
71+
72+
setCommand(button1,refreshMenuCommand)
73+
setCommand(button2,addSubMenuCommand)
74+
setCommand(button3,delSubMenuCommand)
75+
76+
// 以上只是一个很简单的命令模式示例,但从中可以看到我们是如何把请求发送者和请求接收 者解耦开的
77+
78+
//JavaScript 中的命令模式
79+
var bindClick = function(button,func){
80+
button.onclick = func;
81+
}
82+
83+
84+
var setCommand = function(button,func){
85+
button.onclick = function(){
86+
func()
87+
}
88+
}
89+
90+
var MenuBar = {
91+
refresh:function(){
92+
console.log('refresh')
93+
}
94+
}
95+
96+
var RefreshMenuCommand = function(receiver){
97+
return {
98+
excute:function(){
99+
receiver.refresh();
100+
}
101+
}
102+
}
103+
104+
var refreshMenuCommand = RefreshMenuCommand(MenuBar);
105+
106+
setCommand(button1,refreshMenuCommand);
107+
108+
var setCommand = function(button,command){
109+
button.onclick = function(){
110+
command.execute();
111+
}
112+
}
113+
114+
//命令模式撤销 可以用文本编辑器 ctrl + Z. 悔棋的功能 ,动画回退到之前的动作
115+
116+
//撤销和重做
117+
118+
//命令队列
119+
// 所以我们可以把 div 的这些运动过程都封装成命令对象,再把它们压进一个队列堆栈,
120+
// 当动 画执行完,也就是当前 command 对象的职责完成之后,会主动通知队列,
121+
// 此时取出正在队列中等 待的第一个命令对象,并且执行它
122+
123+
124+
// 宏命令是一组命令的集合,通过执行宏命令的方式,可以一次执行一批命令
125+
var closeDoorCommand = {
126+
execute:function(){
127+
console.log('close door')
128+
}
129+
}
130+
131+
var openPcCommand = {
132+
execute:function(){
133+
console.log('开电脑')
134+
}
135+
}
136+
137+
var openQQCommand = {
138+
execute:function(){
139+
console.log('登录QQ')
140+
}
141+
}
142+
143+
var MacroCommand = function(){
144+
return {
145+
commandList:[]
146+
add:function(command){
147+
this.commandList.push(command)
148+
},
149+
execute:function(){
150+
for(var i = 0, command;command = this.commandList[i++];){
151+
command.execute()
152+
}
153+
}
154+
}
155+
}
156+
157+
var macroCommand = MacroCommand();
158+
macroCommand.add(closeDoorCommand);
159+
macroCommand.add(openPcCommand);
160+
macroCommand.add(openQQCommand);
161+
162+
//智能命令和傻瓜命令
163+
//没有接收者的智能命令,退化到和策略模式非常相近,
164+
var closeDoorCommand = {
165+
execute:function(){
166+
console.log('关门');
167+
}
168+
}
169+

0 commit comments

Comments
 (0)