Real World: iOS Design Patterns

Design Pattern is a common topic in talks, forums and even in a 15 min break conversation at work. You can find a lot of stuff on books or the internet about it and a lot of examples using rubber ducks 🦆, coffee shop ☕ and pizza stores 🍕.

When I started studying I usually understand the pattern but I had a lot of trouble, thinking about how to apply them to my code. I understand that the Factory pattern is used to create objects but why do I need it? Do I really need a Factory to create my objects?

My goal with this post is to bring some real examples of some design patterns that I used in my projects.

Strategy

The strategy pattern enables selecting an algorithm at runtime. Instead of implementing a single algorithm directly, code receives runtime instructions as to which in a family of algorithms to use.

We can use different algorithms runtime based, in other words, we don't care how the implementation is done.

An algorithm needs an object that knows how to fly, a Duck class knows how to fly and a Rocket class too. Our algorithm doesn't care if our implementation needs to spread its wings or a gallon of gas.

Problem solved using strategy

It this project we needed to be able to receive a viewController but we also need it to have some predefined behaviors and that's a perfect place to apply the Strategy pattern. A common ViewController in mobile applications is a Login so just create a protocol that defines our LoginViewController actions and dependencies.

I mean that our LoginViewController can be injected in our project, we don't care about the UI if it has a tableView, any animation, or validation methods but we need it to know how to perform a login. You can read more about this particular problem here.

Factory

The factory method pattern deal with the problem of creating objects without having to specify the exact class of the object that will be created.

The factory pattern is useful when you need to create objects at runtime. So if the user wants a cheese pizza you create a CheesePizza() if he/she wants a pepperoni so PepperoniPizza() ftw.

Problem solved using factory

In the same project that we use the strategy pattern to solve our viewController injection problem, we use a factory pattern to be able to create objects at runtime passing to them all the dependencies they need.

We needed to push an instance of LoginViewController which can be created using different approaches like Storyboards , xib or view coded . We had a factory instance, which can be injected changing the way the object that will be created by the factory changing the factory itself.

With an instance of a Factory we just need to call the build method. This factory can be an instance of ViewCodedLoginViewControllerFactory or StoryboardLoginViewControllerFactory we don't really care, we just need it to implement the build method that returns a LoginViewController .

Here we have one factory for each kinds of objects, but we can have one factory that knows how to build a ViewController from storyboard, xibs or viewcoded .

Decorator

The decorator pattern allows the behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class.

This is my favorite pattern, the classic example of decorator pattern is the Coffee shop that wants to add whip cream to its coffee and calculate the new price and description based on the beverage.

Problem solved using decorator

We need different API versions for each service call, this can be done in many different ways but we use this pattern to add a custom Header to a Request. With this approach, we can also be ready if, in the future, one API call should add another parameter to its header.

We also needed to filter results in a request. Which can be done creating a new method, or changing how your request work. We decided to use a Decorator to add this behavior because our service was used in others classes and we want to change the least possible numbers of lines in our previous implementation.

Adapter

The adapter pattern is a software design pattern that allows the interface of an existing class to be used as another interface. It is often used to make existing classes work with others without modifying their source code.

Think an adapter as a real adapter. You need your Nintendo 64 🎮 that has a composite video as its video output to work with your new 4k TV 📺. So you need a Composite-HDMI adapter.

Problem solved using adapter

We needed to last four digits of a Card model and also be compatible with PKPaymentPass. In other words, created an adapter to turn one PKPaymentPass instance into Card.

But we can also mix patterns creating more reusable and maintainable code, for example, mixing our adapter with the strategy pattern. We don't really need a Card object we just need the lastNumbers so why we don't create a protocol to do that and be compatible with PKPaymentPass , Card and any other object that our project may need.

Finally

Design patterns help me a lot to create more reusable code, save me some time when I needed to change some stuff on codes and because of them, some tasks are much easier then they should be.

If you don't get it how the patterns work here are some great posts about Strategy, Factory, Decorator, and Adapter.

Ps: If you like this post, share it on Twitter, recommend it on medium, or both =). This really helps me to reach more people. Thanks a lot.