Learn Swift Command Design Pattern in 3 minutes
Happy new year everyone! back to design pattern series :]
What is Command Design Pattern?
Command design pattern is behavioural pattern that encapsulate command or action as an object. Command design pattern commonly has three main components which are Invoker, Command, and Receiver.
Invoker is a component that has responsibilities to store and execute the commands. Command is a component that wrap an action and encapsulate it as an object. Receiver is a component that acted based on the command. Let see the following code to give you better introduction:
Here I created a simple receiver object called Alarm. It has one property
isOn and later it can changed based on the given command.
AlarmCommand is an abstract interface we used for determine the spec for the command. When we want to create a new command, we can create a new type and conform the AlarmCommand interface. For example in the code above, we can create concrete command implementation which are TurnOnAlarmCommand and TurnOffAlarmCommand.
Last we created the Invoker. The example above is a little bit random by the way but I hope you got the point here :]. Like our discussion before, the Invoker is object that store and execute the commands. The AlarmInvoker receive an Alarm object as an argument and then we create the commands object based on the random number. If the random number is even, then we append TurnOnAlarmCommand otherwise, we append TurnOffAlarmCommand. The AlarmInvoker has one function called
execute, this function is used to execute the command inside the invoker.
Bad Example, isn’t it? :]
So how we can use this design pattern to fix real world problem? I give you one example. In my experience, I often saw a common problem about massive AppDelegate or SceneDelegate implementation. In a big application, we often use so many third-party libraries right? at some point we need to do some initialization or setup the library inside AppDelegate. If we not manage this properly, it would become massive implementation and violating Single-Responsibility principle. Understanding this requirement, so how we can achieve it with nice and elegant solution? please take a look at this simple architecture diagram.
Inside AppDelegate, we would need one object to store and execute all commands, which is in this case is AppInvoker. Then we need an abstract type to determine the spec of the command, we created AppCommand interface with one function as a requirement. After we defined the command interface, we can create concrete command type for example FirebaseCommand and OneSignalCommand. Here is the example code implementation:
After all commands already defined, we can continue to create the Invoker object.
It’s simple right? and here is the final implementation inside AppDelegate.
Voila, congratulation now your AppDelegate is really clean and elegant :]. That’s one of many example you can use command design pattern in Swift and iOS.
Where to go from here
Congratulation, you know have a new insight about command design pattern. Again, understanding the design pattern is quite important as a software engineer so you can have so many weapons to tackle your daily problem. Thank you for reading this article, if you have a question or feedback please leave it to the comment bellow and I will appreciate it so much! Thank you again and happy new year 2022 :]