Learning the Command Pattern in JavaScript
Learning the Command Pattern in JavaScript
The Command pattern is useful for encapsulating objects. This allows developers to separate objects that request and those that wish to invoke a particular method. The Command Pattern is arguably the most common method used among developers and can be found in many popular JavaScript libraries. As the name itself implies, the Command Pattern is named for its style of implementation. Most of the time they include common operations like execute(). Objects in the Command pattern have the same interface and can be quickly exchanged when needed.
var InventoryManager = {
getInfo: function(item, item_id){
return "Item is : " +item+ " with item id: " +item_id;
},
acquireItem: function(item, item_id){
return "Item purchased";
},
sortItems: function(item, item_id){
return "You have sorted the items";
}
}
Based on the code above we can see that the InventoryManager can access objects directly. However, it may not be good practice to be able to access objects directly when it comes to complex or sensitive code. Take for example, if one of the core programs of the InventoryManager is changed, this will probably require all objects to be modified as well.
Let’s add some additional functions with the Command Pattern.
InventoryManager.execute = function(name){
return InventoryManager[name] && InventoryManager[name].apply( CarManager, [].slice.call(arguments, 1) );
};
console.log(InventoryManager.execute("Powder", "1123"));
As you can see from the example above, you can pass a method name and parameters that can be performed on the InventoryManager object, passing with any data that it might request.
Let’s dive deeper with the Command Pattern. Basically it has four parts: the object, client, invoker and receiver.
The client code is responsible for creating the command object and passes it to the invoker. Meanwhile the invoker is the object that will utilize the command object and use what methods are being passed. And lastly, the receiver is the object on what the command is calling.
// Command Pattern
Tasker = (function(){
var executor = {};
var commands = {};
executor.handle = function(commandName, callback){
var commandHandler = {
ref: this,
callback: callback
};
commands[commandName] = commandHandler;
};
Tasker.execute = function(commandName, data){
var cmd = commands[commandName];
if (cmd){
cmd.callback.call(cmd.ref, data);
}
};
return executor;
})();
// Form
(function(Tasker){
var btnSay = $("#sayit");
var lblWord = $("#saythis");
btnSay.click(function(e){
e.preventDefault();
Tasker.execute("doit", lblWord.val());
});
})(Tasker);
(function(Tasker, $){
var showTheText = function(data){
var el = $("#showit");
el.text("You told me to say: '" + data + "', so I did.");
};
// handle the command
Tasker.handle("doit", showTheText);
})(Tasker, jQuery);
The code above is a sample that uses the Command Pattern in displaying a simple text on a form and upon pressing the submit button the word will be passed to a label. In this case, the tasker will be called when the button is selected and passes it to the execute function in which it will be shown dynamically as text every time the “Say” Button is pressed.
Here’s another example. Perhaps we want to create a working calculator. The Calculator object that we are going to create will have four functions: addition, subtraction, multiplication and division.
var Calculator={
// addition function
add: function(num1,num2) {
return num1+num2;
},
// subtraction function
substract: function(num1, num2) {
return num1-num2;
},
// multiplication function
multiply: function(num1, num2) {
return num1*num2;
},
// division function
divide: function(num1, num2) {
return num1/num2;
},
};
In order to invoke its function you can call it by Calculator.add for addition, Calculator.divide for division and so on and so forth. However, there are situations in which we do not need to invoke other methods in the Calculator object directly, the reason being that we don’t want to increase the dependencies among objects. In other words, if the internal methods inside the Calculator are change, the developer who is using the Calculator object would have to modify the code to greatly associate with the changes. With the command pattern we can easily improve the design.
So we added this function.
Calculator.calc=function(command) {
return Calculator[command.type](command.num1,command.num2);
};
Basically, what this function does is to serve as the command center of the Calculator object. Here we are sending the Calculator object the type of command we would like to invoke and the parameters that we would like to pass in depending on the functions parameters. In this case all of our functions accept two parameters.
To check if it works, here are the four examples that we are trying to pass to the Calculator objects.
console.log(Calculator.calc({type: "divide" ,num1:1,num2:6}));
console.log(Calculator.calc({type: "multiply" ,num1:3,num2:5}));
console.log(Calculator.calc({type: "substract" ,num1:4,num2:7}));
console.log(Calculator.calc({type: "add" ,num1:6,num2:3}));
Calling them is simple, and you need to so is invoke the Calculator.calc method that requires the “command” name or in our case the function name of the Calculator object that we would like to invoke. And the next one is the parameters that we need to pass to the method. In this case we passed two numbers.
Be sure to check out our other articles on JavaScript patterns or,
Visit DiscoverSDK.com to compare JavaScript development tools.
Recent Stories
Top DiscoverSDK Experts
Compare Products
Select up to three two products to compare by clicking on the compare icon () of each product.
{{compareToolModel.Error}}
{{CommentsModel.TotalCount}} Comments
Your Comment