JavaScript Design Patterns: Command

The Command Pattern is a strange beast in the context of object-oriented programming. Unlike most objects, a command object represents a verb, rather than a noun. This is a little less odd in a language like JavaScript where functions are actually a type of object, but the classical sense of the Command pattern is still different than a function.

Another Design Pattern

This post is the 11th post in a series about design patterns in JavaScript. To see the other patterns that have been posted and the expected future posts, check out the list just below or at the bottom of the page.

What is the Command Pattern?

As I said, a command object is actually representative of a verb, rather than a noun like most objects are. Another way to say it is that the command pattern is a way of encapsulating the invocation of a method. It is simply an abstraction layer between the object that implements a method and the object that wishes to invoke that method. This is most powerful in the world of user interface. As usual, this will probably make a little more sense with a code example.

Let’s say that we’re making an alarm clock app, probably very similar to the one on your cell phone. It lists several alarms that you can have, and in the case of this app that number can be anywhere between zero and infinity, unlike the mere 4 alarms that my little flip phone maxes out at. For this app we’ll need an Alarm object that contains the status and settings of the alarm. Right now, we’re only concerned about a few specific methods that it implements: enable, disable, reset, and set.

For each one of these methods, we’ll create a command object to encapsulate it:

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
var EnableAlarm = function(alarm) {
this.alarm = alarm;
}
EnableAlarm.prototype.execute = function () {
this.alarm.enable();
}

var DisableAlarm = function(alarm) {
this.alarm = alarm;
}
DisableAlarm.prototype.execute = function () {
this.alarm.disable();
}

var ResetAlarm = function(alarm) {
this.alarm = alarm;
}
ResetAlarm.prototype.execute = function () {
this.alarm.reset();
}

var SetAlarm = function(alarm) {
this.alarm = alarm;
}
SetAlarm.prototype.execute = function () {
this.alarm.set();
}

Notice that the command objects each follow an interface. In this example, the interface defines only one method and each of those methods only calls one function themselves. If this is the case, you probably can just ignore doing things like this and just use callback functions, which is essentially using the functions as the command objects themselves, in which case you’re still using the command pattern but you don’t realize it because it’s always just been called a callback function.

Now we’ll need to use the command objects. We’ll be giving them over to a UI object that adds a button to the screen and when the button is clicked it runs the execute method on the command object that was passed into it. Of course, it knows which method to invoke because all of the commands use the same interface.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var alarms = [/* array of alarms */],
i = 0, len = alarms.length;

for (; i < len; i++) {
var enable_alarm = new EnableAlarm(alarms[i]),
disable_alarm = new DisableAlarm(alarms[i]),
reset_alarm = new ResetAlarm(alarms[i]),
set_alarm = new SetAlarm(alarms[i]);

new Button('enable', enable_alarm);
new Button('disable', disable_alarm);
new Button('reset', reset_alarm);
new Button('set', set_alarm);
}

The 4 Parts of the Command Pattern

The Command pattern has four main parts that make it up. The first and most obvious is the command object. By now you know what this is. The other three parts are the client, invoker, and receiver. The client is the code that creates the command object and passes it on to the invoker. That would mean that in the previous code snippet, the code within the for loop is the client. The invoker is the object that utilizes the command object and calls its method(s). Finally, the receiver is the object that the command is making calls on, which in this case are the Alarms.

Without all 4 of these parts, it’s not the Command Pattern. Knowing this, you may think that what I said about a callback function being considered the Command Pattern is wrong then, right? Well I disagree a bit. I believe that JavaScript is just awesome enough to have made functions be able to operate as their own command objects. All 4 pieces are there, it just so happens that the command object is contained within the receiver. The only argument that I might see as valid is that there is no longer another level of abstraction. You see, the client now has to know what the name of the function on the receiver is, whereas previously the client didn’t need to know that, however, they needed to know about the command objects instead. You lose the abstraction and therefore a bit of modularity, but you gain simpler to understand and faster code.

If you’d like to see an example of something that is a compromise between the above example of command object and just using callbacks, then take a look below, where I use “callback factories” (functions that create callbacks):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var createEnableCommand = function (alarm) {
return function() {
alarm.enable();
}
}

var createDisableCommand = function (alarm) {
return function() {
alarm.disable();
}
}

var createResetCommand = function (alarm) {
return function() {
alarm.reset();
}
}

var createSetCommand = function (alarm) {
return function() {
alarm.set();
}
}

Not much to it. Instead of creating an object that has a method to be called, we just create a function that returns a callback. It’s mostly useless unless it’ll actually do more than just call the one specific function. The primary reason the Command Pattern exists as an object that follows an interface is simply because first-class functions (and/or lambdas) don’t (or previously didn’t) exist in the languages this pattern was designed for.

This can also be used as a means to make your code a bit more secure. Assuming that the invoker is third party code, it could possibly make alterations to the receiver’s method by adding, changing, or nullifying its properties. This is extremely unlikely though.

Here’s what the invoker code looks like when adjusted to use the callback factories:

1
2
3
4
5
6
7
8
9
var alarms = [/* array of alarms */],
i = 0, len = alarms.length;

for (; i < len; i++) {
new Button('enable', createEnableCommand(alarms[i]));
new Button('disable', createDisableCommand(alarms[i]));
new Button('reset', createResetCommand(alarms[i]));
new Button('set', createSetCommand(alarms[i]));
}

I Command You to Finish This

That’s just about all I have. I didn’t mention that the command pattern can be used as a means to create the ability to undo actions as well, but I don’t want to drag this on too long, so I won’t show you how to do this. Outside of using plain callbacks, the Command pattern has pretty limited use. There are times where it can come in quite handy, though, and you’ll feel pretty special for having utilized a design pattern.

On a final note, as usual the list of other posts in the JavaScript Design Patterns series is just below. I’d also seriously appreciate any help spreading the news about this blog, so if you could use the sharing buttons below or even just leave a comment telling me how much you loved/hated this tutorial, I would greatly appreciate it. As always: Happy Coding!

JavaScript Design Patterns series:

Author: Joe Zimmerman

Author: Joe Zimmerman Joe Zimmerman has been doing web development ever since he found an HTML book on his dad's shelf when he was 12. Since then, JavaScript has grown in popularity and he has become passionate about it. He also loves to teach others though his blog and other popular blogs. When he's not writing code, he's spending time with his wife and children and leading them in God's Word.