Command Design Pattern in Ruby

1. Definition

The Command Design Pattern encapsulates a request as an object, thereby allowing for parameterization of clients with different requests, queuing of requests, and logging the operations. It also provides support for undoable operations.

2. Problem Statement

Consider a scenario where you have various operations or requests, and you want to decouple the objects that invoke these operations from the objects that perform them. You might also want the flexibility to queue, log, or support undo-redo functionalities for these operations.

3. Solution

Command pattern introduces command objects. Each command object knows how to perform an operation, and it decouples the invoker from the receiver. You can queue commands, log them, or even implement undo and redo features.

4. Real-World Use Cases

1. Remote control system where each button press is a command.

2. Task scheduling or job queue systems.

3. Undo-redo functionality in software like word processors or graphic editors.

5. Implementation Steps

1. Define a command interface with an 'execute' method.

2. Create one or more concrete classes that implement this command interface for specific actions.

3. Define an invoker class to keep and execute these commands.

6. Implementation in Ruby

# Step 1: Command Interface class Command def execute raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'" end end # Step 2: Concrete Command Classes class LightOnCommand < Command def initialize(light) @light = light end def execute @light.turn_on end end class LightOffCommand < Command def initialize(light) @light = light end def execute @light.turn_off end end # Receiver class class Light def turn_on "Light is ON" end def turn_off "Light is OFF" end end # Step 3: Invoker Class class RemoteControl def submit(command) command.execute end end # Client code light = Light.new turn_on = LightOnCommand.new(light) turn_off = LightOffCommand.new(light) remote = RemoteControl.new puts remote.submit(turn_on) puts remote.submit(turn_off) 

Output:

Light is ON Light is OFF 

Explanation:

1. Command is an interface that declares the execute method.

2. LightOnCommand and LightOffCommand are concrete commands that encapsulate a request to a Light object.

3. RemoteControl is an invoker. It asks the command to carry out the request.

4. In the client code, we initialize a Light, wrap its on and off operations with respective commands, and then use a RemoteControl to invoke these commands.

7. When to use?

Use the Command Pattern when:

1. You need to decouple an object that invokes an operation from the one that knows how to perform it.

2. You want to support undo, redo, or other queue and logging operations.

3. You want to parameterize objects with operations.


Comments