Command Design Pattern in Swift

1. Definition

The Command Design Pattern encapsulates a request as an object, thereby allowing users to parameterize clients with different requests, queue requests, and support undoable operations. In essence, it decouples the object that invokes the operation from the one that knows how to perform it.

2. Problem Statement

Consider a situation where you're building a remote control for various home appliances. If you implement every function for every device directly in the remote, adding new devices or changing the behavior of existing devices becomes cumbersome and leads to a tightly-coupled system.

3. Solution

Using the Command pattern, each operation is encapsulated as a separate object. These command objects can then be used interchangeably, making the system flexible and extensible.

4. Real-World Use Cases

1. Remote controls for electronic devices.

2. Macro recording and execution in software applications.

3. Multi-level undo/redo features in software tools.

5. Implementation Steps

1. Define a command interface with an execute method.

2. Create one or more concrete classes that implement this command interface, encapsulating the action.

3. Define an invoker class that holds a command and can call its execute method.

6. Implementation in Swift Programming

// 1. Command interface
protocol Command {
    func execute()
}
// 2. Concrete Commands
class LightOnCommand: Command {
    func execute() {
        print("Light is ON")
    }
}
class LightOffCommand: Command {
    func execute() {
        print("Light is OFF")
    }
}
// 3. Invoker
class RemoteControl {
    private var command: Command
    init(command: Command) {
        self.command = command
    }
    func pressButton() {
        command.execute()
    }
}
// Client Code
let lightOn = LightOnCommand()
let lightOff = LightOffCommand()
let remote = RemoteControl(command: lightOn)
remote.pressButton()
let remote2 = RemoteControl(command: lightOff)
remote2.pressButton()

Output:

Light is ON
Light is OFF

Explanation:

1. The Command protocol represents the interface for executing an operation.

2. LightOnCommand and LightOffCommand are concrete implementations of the Command protocol, encapsulating different actions.

3. RemoteControl acts as an invoker. It's given a command and invokes it when its method is called.

4. In the client code, we create concrete command instances and pass them to the invoker. When the invoker's method is called, it triggers the encapsulated command's action.

7. When to use?

Use the Command pattern when:

1. You need to parameterize objects with operations.

2. You need to queue operations, schedule their execution, or execute them remotely.

3. You need support for undo/redo functionality.


Comments