命令模式 比喻定义
某位客人点餐或着打电话定餐后,服务员把他的需求定在订清单上,然后交给后厨,客人不用关心是哪个厨师帮他炒菜。客人可以要求延迟炒菜,或取消订单,只要订单在厨师便不会忘记。点餐人过多,厨师还可以按单餐的顺序炒菜.
记录订餐信息的清单,便是命令模式中的命令对象
命令模式中的指令指的是一个执行某些特定事情的指令
常见应用场景
有时候需求向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是什么。希望用一种松耦合的方式来设计 程序 ,使得请求发者和请求接收者能够消除彼此之间的耦合关系。
Javascript中的命令模式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 var bindClick = function ( button, func ) { button.addEventListener('click' , func, false ); }; var MenuBar = { refresh: function ( ) { console .log('refresh menu!' ); } }; var SubMenu = { add: function ( ) { console .log('add sub menu!' ); }, del: function ( ) { console .log('del sub menu!' ); } }; bindClick( button1, MenuBar.refresh ); bindClick( button2, SubMenu.add ); bindClick( button3, SubMenu.del );
upgrade 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 var setCommand = function ( button, func ) { button.addEventListener('click' , func, false ); }; var MenuBar = { refresh: function ( ) { console .log('refresh menu!' ); }; }; var RefreshMenuBarCommand = function ( receiver ) { return function ( ) { receiver.refresh(); } }; var refreshMenuBarCommand = RefreshMenuBarCommnad( MenuBar );setCommand( button1, refreshMenuBarCommand ); var RefreshMenuBarCommand = function ( receiver ) { return { execute: function ( ) { receiver.refresh(); } }; }; var setCommand = function ( button, command ) { button.addEventListener( 'click' , function ( ) { command.execute(); }, false ); };
撤销命令 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 cancleBtn = docuemnt.getElementById('cancleBtn' );var MoveCommand = function ( receiver, pos ) { this .reciver = receiver; this .pos = pos; this .oldPos = null ; }; MoveCommnad.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.addEventListener('click' , function ( ) { var animae = new Animate('ball' ); moveCommand = new MoveCommand( animate, pos.value); moveCommand.execute(); }, false ); cancleBtn.addEventListener('click' , function ( ) { moveCommand.undo(); }, false );
撤销和重做 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 var Ryu = { attack: function ( ) { console .log('攻击' ); }, defense: function ( ) { console .log('防御' ); }, jump: function ( ) { console .log('跳跃' ); }, crouch: function ( ) { console .log('蹲下' ); } }; var makeCommand = function ( receiver, state ) { return function ( ) { receiver[state](); } }; var commands = { '119' : 'jump' , '115' : 'crouch' , '97' : 'defense' , '100' : 'attack' }; var commandStack = [];document .addEventListener('keypress' , function (ev ) { var keyCode = ev.keyCode, command = makeCommand( Ryu, commands[ keyCode ] ); if (command) { command(); commandStack.push( command ); } document .getElementById('replay' ).addEventListener('click' , function ( ) { var command; while (command = commandStack.shift()) { command(); } }, false ); }, false );
宏命令 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 var closeDoorCommand = { execute: function ( ) { console .log('colse door!' ); }; }; var openPcCommand = { execute: function ( ) { console .log('open pc!' ); }; }; var openQQCommand = { execute: function ( ) { console .log('login QQ!' ); } }; var MacroCommand = function ( ) { return { commandList: [], add: function (command ) { this .commandList.push(command); }, execute: function ( ) { this .commandList.forEach(function (command ) { command.execute(); }); } }; }; var macroCommand = MacroCommand();macroCommand.add( colseDoorCommand ); macroCommand.add( openPcCommand ); macroCommand.add( openQqCommand ); macroCommand.execute();
智能命令与傻瓜命令 closeDoorCommand 中没有包含任何recevier,包含recevier的叫傻瓜命令,能更好的解藕; 不包含的叫智能命令。
拓展:对比一下,函数的传参与不传参。 拓展:什么东西叫纯函数?
最終更新:2019-03-05 22:45:54
这里可以写作者留言,标签和 hexo 中所有变量及辅助函数等均可调用,示例:
https://ryansuen.github.io/2018/07/21/设计模式命令模式/