刚看到命令模式的时候,感觉这不就是通常写代码的方式吗,单独算作一种模式有什么意义呢?寥寥几行的代码就可以实现的东西为什么要搞这么复杂?
诚然,设计模式起源于强类型的语言,对JavaScript这种动态语言来说,函数可以作为参数四处传递并在任意位置灵活的进行调用,似乎无需显式地构造一个用于命令模式调用的对象,但是,语言内置的命令模式和软件开发过程中的命令模式要解决问题其实是有所不同的,一种语言固然可以使得任何函数都可以被当作命令来调用,但是在团队开发中,我们应该尽可能地使得功能与功能之间的耦合减弱,并对调用接口做出统一的、辨识度高的规范,而设计模式正是一种可以作为团队内部进行高效沟通的桥梁,使得代码更加规范,可读性得到提高。
示例:小球动画轨迹的返回运动
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
| var ball = document.getElementById('ball'); var pos = document.getElementById('pos'); var moveBtn = document.getElementById('moveBtn'); var cancelBtn = document.getElementById('cancelBtn');
var MoveCommand=function(receiver,pos){ this.receiver=receiver; this.pos=pos; this.oldPos=null; }; MoveCommand.prototype.execute=function(){ this.receiver.start('left',this.pos,1000,'strongEaseOut'); this.oldPos=this.receiver.dom.getBoundingClientRect()[this.receiver.propertyName]; }; MoveCommand.prototype.undo = function(){ this.receiver.start('left',this.oldPos,1000,'strongEaseOut'); }; var moveCommand; moveBtn.onclick = function(){ var animate = new Animate( ball ); moveCommand = new MoveCommand( animate, pos.value ); moveCommand.execute(); }; cancelBtn.onclick = function(){ moveCommand.undo(); };
|
宏命令–下达一组命令
宏命令是指将一系列命令模式的命令集中在一条指令中,以达到同时下达多个命令操作的效果。通常的做法,是将命令模式下的命令放进队列(数组)中,并根据需求以恰当的方式一次执行,比如在命令中存在异步操作时,我们需要根据实际需要决定这些异步操作是以并发的形式发出还是以同步的形式逐次执行。
例:
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
| let commanda={ execute:function(){ fetch('...',{}).then(...) } }, commandb={ execute:function(){ fetch('...',{}).then(...) } }
let macroCommanda=function(){ let commandlist=[]; return { add:function(command){ commandlist.push(command); }, execute:function(){ commandlist.forEach(function(command){ command.execute(); }) } } } let macroa=new macroCommanda(); macroa.add(commanda); macroa.add(commandb); macroa.execute();
let macroCommandb=function(){ let commandlist=[]; return { add:function(command){ commandlist.push(command); }, execute:async function(){ commandlist.forEach(function(command){ await command.execute(); }) } } } let macrob=new macroCommandb(); macroa.add(commanda); macroa.add(commandb); macroa.execute();
|