Design Patterns in Swift: Command Pattern Explained

Design Patterns in Swift: Command Pattern Explained

Design patterns are an integral part of modern software development. They provide a way to structure code and make it more maintainable, extensible, and testable. In this article, we will explore the Command Pattern in Swift. We’ll look at what it is, when to use it, and how to implement it.

The Command Pattern is a behavioral design pattern that allows us to encapsulate a request as an object. This object can then be passed around a system, allowing the same code to be used in different contexts. It also allows us to queue up multiple requests and execute them in order.

At its core, the Command Pattern is about decoupling the sender of a request from the receiver. The sender doesn’t need to know who the receiver is or how the request will be handled. This makes it easier to add new receivers and modify existing ones without having to change the sender.

Let’s take a look at an example of the Command Pattern in action. Suppose we have a system that needs to be able to turn lights on and off. We could create a LightOnCommand and a LightOffCommand class that encapsulate the request to turn the light on or off. These classes could then be passed to a LightSwitch class, which would execute the command and turn the light on or off.


class LightOnCommand {
  let light: Light

  init(light: Light) {
    self.light = light
  }

  func execute() {
    light.on()
  }
}

class LightOffCommand {
  let light: Light

  init(light: Light) {
    self.light = light
  }

  func execute() {
    light.off()
  }
}

class LightSwitch {
  let onCommand: Command
  let offCommand: Command

  init(onCommand: Command, offCommand: Command) {
    self.onCommand = onCommand
    self.offCommand = offCommand
  }

  func on() {
    onCommand.execute()
  }

  func off() {
    offCommand.execute()
  }
}

class Light {
  func on() {
    print("Light is on")
  }

  func off() {
    print("Light is off")
  }
}

let light = Light()
let onCommand = LightOnCommand(light: light)
let offCommand = LightOffCommand(light: light)
let switchControl = LightSwitch(onCommand: onCommand, offCommand: offCommand)
switchControl.on()  // Light is on
switchControl.off() // Light is off

In this example, we have a LightSwitch class that takes a Command object as a parameter in its constructor. When the LightSwitch’s on() or off() methods are called, the corresponding Command object is executed. This allows us to decouple the LightSwitch from the Light object.

The Command Pattern is especially useful in applications where we need to queue up multiple requests and execute them in order. For example, if we had a system that needed to turn on a light, open a window, and start a fan, we could create three Command objects and add them to a queue. Then, we could process the queue one item at a time, turning on the light, opening the window, and starting the fan in order.

The Command Pattern is also useful for undo operations. By keeping track of all the commands that have been executed, we can easily roll back changes by executing the inverse of the last command. This makes it easy to undo errors and handle user input.

In summary, the Command Pattern is a powerful tool for decoupling components in a system. It allows us to queue up multiple requests and process them in order. It also provides a way to undo operations and handle user input. With the Command Pattern, it’s easy to add new commands and receivers without having to change existing code.

If you’re looking for a way to structure your code and make it more maintainable, extensible, and testable, the Command Pattern is a great option. It’s relatively easy to implement and provides a lot of flexibility.

Scroll to Top