Command mode is one of the simplest and most elegant modes. A command in command mode refers to an instruction that does something specific.

Application scenarios

Sometimes you need to send a request to some object without knowing who the recipient of the request is or what operation is being requested. At this point, you want to design the program in a loosely coupled way so that the request sender and the request receiver can decouple from each other.

  • Menu case

Suppose we are writing a user interface program with at least dozens of buttons. Because of the complexity of the project, we decided that one programmer would be responsible for drawing the buttons, while another programmer would be responsible for writing the behavior of clicking the buttons, which would be encapsulated in objects.

This is a normal division of labor in large projects. For the programmer who draws the button, he has no idea what the button will do in the future, whether it will refresh the menu interface or add submenus. He only knows that something will happen when the button is clicked. So how do you bind the onclick event to the button once you’ve drawn it?

We can quickly see the reason for using the command pattern here: after the button is clicked, the request must be sent to some object responsible for the specific behavior, and these objects are the recipients of the request. But it is not known what the recipient is or what exactly the recipient will do. At this point we need the help of a command object to decouple the button from the object responsible for the specific behavior.

  • Code implementation
 var RefreshMenuBarCommand = function( receiver ){
     return {
         execute: function(){ receiver.refresh(); }}}; varsetCommand = function( button, command ){ 
     button.onclick = function(){ command.execute(); }}; var refreshMenuBarCommand = RefreshMenuBarCommand( MenuBar );setCommand( button1, refreshMenuBarCommand );
Copy the code
  • Cancel the order

Command mode not only encapsulates the operation block, but also easily adds undo operations to the command object. Now there is a small ball on the page, click the move button and the undo button to move and undo operations.

  • Code implementation
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 ]; // Record the position of the ball before it starts moving}; MoveCommand.prototype.undo =function(){
   this.receiver.start( 'left', this.oldPos, 1000, 'strongEaseOut'); Return to the position recorded before the ball moved}; var moveCommand; moveBtn.onclick =function(){
   var animate = new Animate( ball );
   moveCommand = new MoveCommand( animate, pos.value );       
   moveCommand.execute();
};
cancelBtn.onclick = function(){ 
   moveCommand.undo();
};
Copy the code
  • macros

A macro command is a set of commands. You can execute a batch of commands at a time by executing macro commands. Imagine that there is a universal remote control in our home. Every day when we go home, as long as we press a special button, it will help us close the door of our room, turn on the computer and log in QQ.

  • Code implementation
var closeDoorCommand = { 
    execute: function(){
        console.log( 'shut down'); }}; var openPcCommand = { execute:function(){
        console.log( 'Turn on the computer'); }}; var openQQCommand = { execute:function(){
        console.log( 'login QQ'); }}; var MacroCommand =function() {return {
           commandsList: [],
           add: function( command ){
              this.commandsList.push( command ); 
           },
           execute: function() {for ( var i = 0, command; command= this.commandsList[ i++ ]; ) { command.execute(); }}}}; var macroCommand = MacroCommand(); macroCommand.add( closeDoorCommand ); macroCommand.add( openPcCommand ); macroCommand.add( openQQCommand ); macroCommand.execute();Copy the code

Series of articles:

JavaScript Design Patterns and Development Practices