Photo by mostafa rzq on Unsplash

Turn a request into an object

Swift — Problems Catalogue #17

Alex Ilovan
Published in
4 min readJan 24, 2023

--

Problem Definition:

Consider the following scenario. You have to implement an app that allows users to control the lights in their home remotely. The user can turn lights on and off, dim them, and set schedules for when the lights should turn on and off.

The app will be developed and released in several phases. We need a way to separate the user interface elements that initiate actions from the classes that know how to perform them in order to make it easy to add new functionality, such as new types of lights or new features, without having to change the existing code.

Problem Solution:

Solution — Command pattern is a behavioral design pattern that turns a request into a stand-alone object that contains all information about the request. This transformation lets you pass requests as a method arguments, delay or queue a request’s execution, and support undo/redo.

Real-World Usage:

First, we define a protocol Command that has a single method execute().

1. Command Protocol

Second, we define a Light class that has two methods: turnOn() and turnOff() that are used by the concrete commands that we will define next.

2. Light Class

The Command protocol is implemented by two classes LightOnCommand and LightOffCommand. These two classes are concrete commands that know how to perform the request. They hold a reference to the Light object and call the corresponding method on it when the execute() method is called.

3. Commands

Next, we define a Switch class that holds references to Command objects for turning on and off the light and it has methods flipUp() and flipDown() which execute the commands. The Switch class holds a reference to both onCommand and offCommand and it executes it when the corresponding flipUp() or flipDown() method is called.

When the flipUp() method is called, in turn calls the execute() method on the onCommand object. The onCommand object then calls the turnOn() method on the light object, which causes the string "The Light is on." to be printed to the console.

Similarly, when the flipDown() method is called, it calls the execute() method on the offCommand object, which in turn calls the turnOff() method on the light object, which causes the string "The Light is off." to be printed to the console.

4. Switch class

Finally, we bring everything together. We create an instance of the Light() class and instances of the concrete commands and we pass the light instance to the instantiated commands.

We then create a Switch instance and we pass the commands. By executing the flipUp() and flipDown() methods, in turn we execute the commands which in turn execute the turnOn() and turnOff() methods defined in the Light class thus having an encapsulated request into an object.

5. Bringing everything together

The advantage of using the Command pattern is that it decouples the object that invokes the operation from the one that knows how to perform it. It allows you to pass method calls as method arguments, delay or queue a request’s execution, and support undo/redo.

From this point on, the sky is the limit 🚀 well…almost.

Of course, this design pattern has its limitations but used in moderation, it’s a great tool in our development toolbox.

This is the next article in the Swift Problems Catalogue series in which I’ll tackle general software development problems. The aim is to have a quick reference guide that can be easily accessed when having a design/algorithm dillemma.

Let me know what you think and don’t be shy to share where and when this pattern simplified your coding experience 🎶

--

--

Alex Ilovan

🚀Head of Mobile Development @S&P 💻Comp. Engineer 🪐Engineering Manager. You can visit at: https://www.linkedin.com/in/alex-ilovan-129161b4/