Strategy Design Pattern in Swift for Beginners
In order to keep the app’s size as low as possible, we need to reuse components as much as possible. In that sense, UI components come to mind first. So it’s very smart to reuse the UI component if the difference is slight.
Although I do not hear about it as much as I expected, this pattern is one of the basic patterns in iOS development. I would highly recommend you master it before progressing further in your iOS developer career. And good news, it’s very similar to Delegate Design Pattern in writing.
What is Strategy Design Pattern?
The strategy pattern specifies a set of interchangeable objects that can be changed or set at runtime. This pattern changes the way the app behaves, so this one is called a behavioral design pattern.
It consists of:
- One class that owns/uses the strategy. This is usually the View Controller, ViewModel, or whatever manages the logic of the view.
- One protocol dictates what a concrete strategy needs to have
- And any set of concrete strategies that conforms to the above protocol.
The owner class changes its behaviors according to the given protocol. It doesn’t know which strategy it’s going to implement. It only knows in which field the strategy is going to give it the information.
When do we use it?
If you have two or more behaviors that are interchangeable, a view that you want to reuse and modify during runtime, use this design pattern.
In another case, if you found yourself making a bunch of if statements to handle various cases in the same view controller, initialize and pass a strategy instead.
Ultimately the goal is to have a cleaner code that is easier to maintain. Check out two ways to set up the UI below.
The latter one is shorter and seems cleaner.
Difference Between Delegate Design Pattern
In terms of additional flexibility, this approach is similar to the delegation design pattern in that both rely on a protocol rather than concrete objects. As a result, any object that implements the strategy protocol at runtime can be utilized as a strategy.
However delegation is more about running functions and passings data through arguments to another class, strategy is about the same class having a variety of usages and behaviors. Delegates are usually decided at runtime. The delegate for a UITableView, for example, can be configured in the view controller or on a storyboard, and they rarely change during runtime. However, at runtime, strategies are meant to be interchangeable.
Start up a playground in Xcode, then start typing the below code.
Create the strategy protocol
The first thing in order is to define what strategy should conform to. Check what fields you are modifying in your view controller and write the property names for instance.
Create the concrete strategy classes
They all conform to the ProductPageStrategy. Every strategy can have its own properties and implementations.
Feed the strategy to the owner class
Below is the fake ViewController for demonstration purposes. In a real example, it will inherit UIViewController, and have viewDidLoad(). However, it should be formed similar to this.
Test the freshly implemented strategy pattern
The first strategy is directly fed to the View Controller inside the init. The others are changed after them since the strategy property is public. You can imagine a button to feed the appropriate strategy during the runtime.
In the future, we do not need to make a modification to the view controller. If a new user type comes up, we can create a new strategy and feed it outside the view controller.
The above example is obviously super simple. Imagine a view controller that has a lot of properties, such as images, subtitles, labels, heights, colors, and so on. That's when this pattern is a lifesaver.
A real-world case
The last time I used this pattern is for a map view. I was developing a map that annotates where the nearest libraries and cafes are located. Then I needed another map that shows only the libraries and has a segmented control on top of it. I created a strategy protocol with properties "searchType" and "shouldHideSegmentedControl" and then created the concrete strategy object by conforming to the protocol. Finally, feed the strategy when I instantiate the view controller that contains the map view and segmented control. This way, I was able to reuse the same map view controller in multiple cases.
Be careful when…
If you don't anticipate further reuse cases for a component, this pattern could be overkill. In particular, it’s OK to place the logic within the consuming view controller or object context if a behavior will never change.
Congratulations. You’ve made it to the end.
This is a great pattern to learn and implement. This will be a great asset to your coding arsenal.
I hope that the above explanation makes sense and will be helpful to you on your iOS development journey.
Thanks for reading. Have a great one.