This post is part of a series of reviews on the book Design Patterns in Ruby. Check out the Introduction post for a full table of contents along with some generic principles regarding Design Patterns.

The Command pattern is nothing more than a standardization of methods: by keeping actions with a same name in multiple places you can ensure that by calling that specific method, something will happen. As you can deduce, delegation and composition play a big part here because the callers will use the objects they’re referencing, or as we might say, issue commands, by delegating the target object a certain method.

Let’s say we code a button class that does something when pushed and say we were hand out this button for other developers to use. Since we can’t predict every possible way the button will be used, we tell them ‘Hey, be sure to pass an object with an execute() method when creating my button’:

class Button
	attr_accessor :command
	
	def initialize(command)
		@command = command
	end
	
	def on_push
		@command.execute if @command
	end
end

This way we avoid supplying a blank on_push() method forcing developers to create a subclass of Button and overwrite it with that they need, which is the main purpose of the Command pattern. Anyway, let’s code the command itself:

class SomeRandomCommand
	def execute
		puts "Look! I've been executed :D"
	end
end

Dang that was hard. Let’s see it working:

b = Button.new(SomeRandomCommand.new)
#something happens and the button is pushed
b.on_push

And it gets even easier: a command is simply a chunk of code that gets executed when his time comes, which ironically is the same thing a block does! Let’s refactor our Button class to use blocks instead.

class Button
	attr_accessor :command
	def initialize(&command)
		@command = command
	end
	
	def on_push
		@command.call if @command
	end
end

b = Button.new do
	puts "Look! I've been executed :D"
end
	
#something happens and the button is pushed
b.on_push

Just like that we got rid of the whole need of creating command classes, which is kind of relative to what you’re doing, using blocks are fine for quick stuff but more complex logic should be stored in a more proper way (classes).

But the cool thing about commands is when you start recording each one of them giving you the ability to undo (and redo) them. Let’s refactor our little Button to be able to store and undo commands:

class Button
	attr_accessor :commands
	def initialize
		@commands = []
	end
	
	def on_push
		@commands.each{|c|c.execute if c}
	end
	
	def undo
		@commands.reverse.each{|c|c.unexecute}
	end
	
	def << (command)
		@commands << command
	end
		
end

class SomeRandomCommand
	def initialize(number)
		@number = number
	end
	
	def execute
		puts "Executing command number #{@number}."
	end
	
	def unexecute
		puts "Undoing command number #{@number}."
	end
end

b = Button.new

3.times do |n|
	b << SomeRandomCommand.new(n+1)
end
	
#something happens and the button is pushed
b.on_push

#oops, there was a mistake, undo everything
b.undo

Whoever’s familiar with Ruby on Rails should have noticed the similarity this has with migrations, they’re nothing more than commands that execute, get stored and have the ability to undo.