Use Strategy Design Pattern to Create Analytic Feature in iOS App

Tifo Audi Alif Putra
Geek Culture
Published in
5 min readNov 15, 2021

--

Strategy design pattern is one of many weapons that we can use to build scalable system.

Photo by Thom Bradley on Unsplash

Analytic tracker feature probably is one of the most important feature that many mobile applications use in these day. We can gain many data from the user daily behaviour when use our app, then we can analyze it to become useful information to determine the next step of our mobile application development.

In practical, there are tons of tools that we can use to implement analytic feature in iOS. Probably we can use Google analytic SDK, or maybe iCloud analytic SDK, or even we can develop analytic tracker SDK by ourself. Then how we design an architecture system to implement analytic tracker feature is quite challenging. We want to achieve scalability, it means we can scale our codebase without need a big cost to do it. We also want that our codebase can be extend easily without breaking the current implementation. Maybe we also want that our codebase can be tested easily. Then how we can achieve this goals?

This is why as an iOS engineer, or even as a mobile developer, understanding how to design system is really important skill that we need to have. Our decision is really important for a long term. Understanding the design principles, and many design patterns will help us to determine “Which weapon that I need to use to handle this problem?”

Introducing Strategy Design Pattern

Strategy design pattern define a set of switchable object that can be set at runtime. Take a look at this simple diagram:

The first component that must exist is we have object that has a dependency and it conform to the strategy protocol. The strategy protocol has requirements that the concrete implementation objects should implement it. To achieve this strategy pattern, we can use dependency injection technique. Take a look to this sample implementation:

We have simple object called HomeRepository. It has one dependency with type LocalStorage and it is a protocol. In a real world, we can implement a local storage with many options like core data, realm, user default, etc. We can create concrete implementations from local storage options and conform it to the LocalStorage protocol.

The diagram from the code above would be like this:

Strategy Design Pattern Benefits

  • It enable us to hide the concrete implementation from the Object that use the strategy. We can change the implementation without breaking the root object implementation.
  • It is testable, with the strategy protocol we can create some object for unit testing purpose like mock or spy object that conform to the strategy protocol.
  • You can think that strategy pattern is a little bit similar with delegation pattern. It use another object to help the object complete it task. However, the purpose of the strategy pattern is we can define switchable concrete implementation and the system is can be extend or change easily.

Then how we can use this strategy pattern to help us develop analytic feature in iOS? well first we need to define the complete requirements and after that we can directly design the system.

Tracker Event

Usually any type of event tracker is required a common data that we need to provide. For example when user open the home page, we need to send the timestamp, device version, OS version, and the event type name. Another example is when user is tap a card on a list, it required the same data like I mentioned before, but maybe we need send additional information like the data serial in the card? or some state in the card?

In order to represent the tracker data in a system, we can use some option like enum, struct, or protocol. Which one is better?
I will go with protocol solution. Why we not use an enum? Usually in a big application, there are hundreds event tracker implementation. If we use an enum, basically it will violating the open close principle because whenever we add a new tracker event type it will break the switch statement implementation and we need to modify it. Struct is better than enum, but protocol is more powerful. I will tell you how to use protocol to achieve this goals.

Like I said before, event type is set of similar data that we need to provide. We can create one protocol to represent this event type like this:

Then if we want to add new analytic tracker, we can create new type and conform to it example above. With this implementation, our diagram would be like this:

Our protocol that represent the tracker event type is done now. The next step is how we create an object that has one responsibility, which is send the event type to the analytic service. Like we already discussed before, the analytic service could be Google Analytic SDK, or another analytic SDK. Guess what? is time to implement strategy pattern!

Like our previous discussion, strategy pattern required one protocol as a strategy abstraction, it has one function requirement which is send analytic tracker data. Our concrete strategy implementation which is GoogleAnalyticService and ICloudAnalyticService is required to implement the strategy protocol requirement. Then the final step is to create the object that use the strategy protocol as its dependency.

Our final system diagram would be like this:

Key Points

Strategy design pattern is one of the most powerful pattern that we can use to create scalable system. It define a switchable concrete implementation that we can use it in a runtime. But as a software engineer, it would be good if you learn about another design patterns and design principles and it will make you have more weapons to solve a real-world problem. Thank you and happy coding :]

--

--