Command Objects Are Gerunds

Command Objects Are Gerunds

Ben Spatafora
Ben Spatafora
July 15, 2014

A gerund—as I often have to remind myself—is a verbal noun. That is, a gerund is a verb being used as a noun. In English, gerunds always end in -ing, though not every word that ends in -ing is a gerund. An example: The verb “to overeat” becomes the gerund “overeating,” as in the sentence, “I enjoy overeating.”

The Command Pattern is a behavioral design pattern that works like a gerund because it takes the coding equivalent of a verb (method) and transforms it into the coding equivalent of a noun (object). This is its essence:

1class SomeCommand
2 def execute
3 # ...
4 end
5end

The idea is that you can make lots of command objects from this class (and other classes that adhere to this “has an execute method” interface), then pass them around your system to entities that know about the interface (i.e., know they can call execute on whatever object they are passed).

This transformation allows for some interesting possibilities. For example, you could dynamically build up a list of commands to be executed together at some later time, a structure that might form the basis for the creation and execution of user-defined macros. Another use with a similar structure is building up and executing a database transaction, where failure on the part of any individual command would prevent the transaction as a whole from being committed.

The Command Pattern can also be purposed to implement undo functionality. Each command object must remember the details of what it did when its execute method was called, and have an undo method to be able to reverse whatever it did.

The Wikipedia article on the Command Pattern contains a simple example of the pattern showing its typical structure. Here’s my version of the example, rewritten in Ruby and a little modified:

 1# Invoker
 2class Invoker
 3 def initialize
 4 @history = []
 5 end
 6
 7 def record_and_execute(command)
 8 @history << command # Optional
 9 command.execute
10 end
11end
12
13# Receiver
14class Light
15 def turn_on
16 puts 'The light is on'
17 end
18
19 def turn_off
20 puts 'The light is off'
21 end
22end
23
24# A command
25class TurnOnCommand
26 def initialize(light)
27 @light = light
28 end
29
30 def execute
31 @light.turn_on
32 end
33end
34
35# Another command
36class TurnOffCommand
37 def initialize(light)
38 @light = light
39 end
40
41 def execute
42 @light.turn_off
43 end
44end
45
46# Client
47class Client
48 def initialize
49 @invoker = Invoker.new
50 @light = Light.new
51 end
52
53 def party
54 50.times do
55 @invoker.record_and_execute(TurnOnCommand.new(@light))
56 @invoker.record_and_execute(TurnOffCommand.new(@light))
57 end
58 end
59end

The example contains four sorts of entities, each with their own responsibility. The receiver does the actual work (in this case, it is a Light object that can be turned on and off). The command objects wrap method calls to the receiver. While client entities can already send a turn_on or turn_off message to a Lamp object, these commands are objects representing the sending of such a message. This may seem like a subtle distinction, but it's the key to how the pattern works.

The client makes decisions about which commands should be created and executed and when these things should occur, and the invoker is the entity that actually calls execute on the command objects. The roles of client and invoker are sometimes represented in the same object, but since they change for different reasons each responsibility should exist in its own entity.

The common thread running through this example and the use cases for the pattern described above is the decoupling of the actual execution of a command from the entity that decided it should be executed. As Uncle Bob puts it, the Command Pattern decouples “what gets done from who does it” and “what gets done from when it gets done.” The key to this decoupling is the reification of something abstract and transitory (a method) into a stable entity (the object).