Using Protocol Inheritance in Swift
In software world, sometimes on the work we do (on the code we write), we wonder if there is a way more conforming to the standards and more maintainable. Although this is not that easy, this curiosity can bring writing more clear, readable code. In this case, the principles and the structures give the project a more testable environment if adopted properly.
I wanted to write an article. This is going to be about using protocols.
Let’s consider the scenario, see the problem and solve in a more effective way.
Scenario
In Trendyol application, there are some pages that send the actions which is taken from the user to the related analytical services like adding product to basket, or clicking the quick filter option. Let’s take a look at these action methods in protocol named TrackingInterface
.
As seen above TrackingInterface
has three required instance methods and exists for sending an event by related pages. First method is for all pages, second for Favorite List and the last for Search Result page.
TrackingInterface
protocol is adopted by FavoriteListPresenter
. When page is loaded sendPageViewedEvent
method is called. When user adds product to basket, the feeding of this action is performed by sendAddToCartEvent
method.
Problem
However, third required method named sendQuickFiltersClickedEvent
which is a part of the TrackingInterface
(owner of the SearchResultPresenter
) is forced to implement and looks redundant for FavoriteListPresenter
. So why this method is known by this presenter?
Solution
Here sendQuickFiltersClickedEvent
method doesn’t make any sense for Favorite List page.
Basically if there is one method which is not adopted by all conforming types, there is no point defining it in protocol scope.
With extension, protocols can have a method, initializer, subscript, and computed property implementations to conforming types. Extensions also allow to provide a common implementations to all conforming types. We have defined extension for TrackingInterface
.
And we’ve cleaned up FavoriteListPresenter
. With this solution it has own required methods.
But wait a second. This method is still a part of FavoriteListPresenter
and this presenter is still reaching this method which is not used in itself. In this scenario,
This solution may be the one way to go, but is this really way to go?
It would be much more clean to separate completely right? Let’s do it!
Protocols can inherit from another protocol(s) at the same time known as Protocol Inheritance. Here, any subtype that adopts FavoriteListTrackingInterface
or SearchResultTrackingInterface
must satisfy all the requirements enforced by TrackingInterface
. Now we can conform what we need separately.
With this approach we,
- rescued
TrackingInterface
from being a fat interface. - implemented The Interface Segregation Principle.
- gave more flexible environment for each subtype even we expand the reusability.
Thanks for reading and happy codings!