Strategy pattern in Swift

Juanpe Catalán
5 min readDec 13, 2018

--

Recently I gave a talk at NSCoder Night Madrid about the Strategy pattern. People loved it! I felt that our community will benefit from this knowledge too. So in this guide, I will explain Strategy pattern for iOS and provide some examples.

What is it?

Firstly we should define this pattern. In Wikipedia, it is defined as follow:

In computer programming, the strategy pattern is a behavioral software design pattern that enables selecting an algorithm at runtime. Instead of implementing a single algorithm directly, code receives run-time instructions as to which in a family of algorithms to use.

🤯 ⁉️ This definition is very theoretical, so I think we could define it easier:

Encapsulates algorithms in classes, making them reusable and interchangeable at runtime.

Classification

The design patterns are classified into 3 categories according to their objectives:

  • Creational
  • Structural
  • Behavioural

Yes, Strategy pattern is a behavioural pattern because it’s related to the behavioural of the objects. Easy, right?

When we should use it

There are many cases when we can use it. Let’s talk about three very specific scenarios in which we can see a clear value of the Strategy pattern.

1️⃣ Different ways to do the same

When you need to do the same thing in your code by different ways, it’s a clear example that you could use it.

2️⃣ Instead of inheritance

If you need to extend the functionality of a class and for doing this, you need to create a new class who inherits from it.

3️⃣ Alternative to if/else blocks

This is my favourite. Sometimes, if you look at a class, you can see that it has too much if/else or switch blocks, I mean, conditional blocks. This is a sign that this class has more responsibilities than it should. Using a Strategy pattern would help you distribute them.

Real Example

Imagine we need to create a Logger class, who prints a message in the console. Also, this class allows you to print stylized messages: lowercase, uppercase and capitalized. So, a possible implementation could be something like this:

https://gist.github.com/Juanpe/61eaf2a160cb48786b80189c812cdb55

Then, we would have an enum to specify which styles are available and a function log with a switch block inside to print the message in the console in the different styles.

Not bad, but really printing the message using different styles is the responsibility of the logger? What happens if we have twenty styles instead of only three? We should modify this class by adding the new styles inside the enum and the log function as well. 😅

According to the scenarios that we saw previously, this could be a good example where Strategy pattern could help us.

To explain how to do it, we will answer three questions and use a diagram, which I extracted from the book Design Patterns by Tutorials, available in Ray Wenderlich’s store, where we can differentiate all the participants very well.

  • What: A protocol that defines the action that we want to encapsulate. In our example, the action would be log a message.
  • Who: An object who contains an object who conforms the strategy. In our example, it could be an object who using the strategy log the message.
  • How: Specific implementations of the strategy. Each implementation is different. In our example, we would have three strategies, one for each style.

So, the previous example using strategy would look like this:

https://gist.github.com/Juanpe/1128f3fdd8615acecd0af22577c16a10

And here how we can use it:

https://gist.github.com/Juanpe/e8e582aa3fac91bf37638d4f5fed442a

More examples

Let’s see more real examples where we can use the Strategy pattern.

📅 Calendar selection

eDreams iOS App screenshots

In my company, eDreams ODIGEO, an online travel agency, users can choose between one-way trips or round trips. So, when we need to open the calendar to select the dates, depending on the type of trip that has been selected, the strategy of selection is different. For example, if it’s a round trip, the return date must be later than the departure date.

So, we have two selection strategies and when we open the calendar we specify which strategy should be used:

https://gist.github.com/Juanpe/e43441aeeb5d43e83db80e05469e306b

👮🏻‍ Form validation

When we use forms in our applications, we have many types of fields, texts, numbers, passwords, emails … In addition, each one has its own validation conditions. Then, we could define a strategy to validate, and each field would know how to validate itself.

https://gist.github.com/Juanpe/4749d6269d7e7368d900bda88d4b8776

🎨 Draw UITableView cells

To draw cells would also be useful. Imagine that we need to draw very different cells. Then, we would have a drawer that, using a view model, would draw the specific cell.

https://gist.github.com/Juanpe/30123af0421999591d9d430acc9f762d

💵‍ Payment in a shopping cart

Methods of payment, exactly, when in our apps we provide several payment methods to pay the shopping cart: cash, cards, checks … In this case, we would use a specific strategy for each method, so when we start the action of payment only we will need to specify the amount and the payment interface.

https://gist.github.com/Juanpe/c1f92f0ce726246978f8e22548c428e7

🔫 Exchange weapons in a game

Changing the context, in the games the player exchanges weapons or shots using them. The action is the same for all weapons, but each weapon has its own way of firing, and the player does not need to know, it is what each weapon knows what to do when the player shots.

Why we should use it

The strategy is one of the most useful and simple design patterns. Also, if we use this pattern, you are doing a lot of things well and maybe you did not know:

Meet some SOLID principles

  1. Single responsibility. When we create strategies to do different things, we get that our original class has fewer responsibilities.
  2. Open / Close. If we use strategies to extend the functionality of the objects we don’t need to update the original object. As in our first example, if would add a new style, we only need to create a new strategy. Otherwise we would need to add a new case in our Styles enum.

Best practices

Use design patterns is a good practice when we are talking about software design.

Code testability

If we reduce the responsibilities of our objects, directly, we will do our objects more testables.

I hope this article helps you to learn a little more the Strategy pattern, that as I said before it has many pros and its implementation is not complex.

Be careful: when we find a new design pattern, we want to use it everywhere. But wait! We must analyze whether we should use it or not. Sometimes we do over-engineering.

Thanks for reading my tutorial. Share it if it was useful for you or if you think could be useful for someone. Feel free to comment below if you have any doubts or any suggestion of improvement.

--

--