iOS — SOLID Principles Pt.4 — Interface Segregation Principle

Roni Leyes
The Aesthetic Programmer
2 min readApr 15, 2018

Interface Segregation Principle says that:

“many client-specific interfaces are better than one general-purpose interface.”

In iOS, Interface in that subject could be translated to Protocol.

It says that many protocols are better than one big protocol (Or class, struct or enum) with one general purpose.

Client-Specific Interfaces

Client Specific Protocol would be a protocol that some client only need.
Let’s say you have two classes:
Cat and Human:

class Human {   func work(){}   func sleep(){}   func giveFood() -> Food{      return Food()   }   //Some more functions}class Cat {   var owner : Human   var foodBowl : [Food] = []
func requestFood(){ print("Meow, gimme food") let foodScoop = self.owner.feedPet() self.foodBowl.append(foodScoop) }
func eat(){ self.foodBowl.removeAll() } init(owner:Human){ self.owner = owner }}

As you can see, Cat is a client of Human. It consumes data from Human.
The Cat can’t tell it’s owner to work, nor does it needs to know about that.
All it needs from his owner in this example is it’s food.

Segregation

That’s where the segregation comes.
As we said, the cat only cares about his food.
There’s no reason for Cat to be exposed to functions of Human like work() or sleep().

so we can declare a PetFoodProvider protocol:

protocol FoodProvider {   func feedPet() -> Food}

So then our client(Cat) would use(and will be exposed to) only what it needs:

var foodProvider : FoodProvider

And we can conform to that in our Human struct(Or even in our automatic cat feeder machine):

struct Human : FoodProvider ....

Decoupling

Decoupling your types and protocols like that has many benefits.
A classic example would be segregating our Human work() function to a new protocol:

protocol Worker {   func work()}

Then we can write an Employer protocol:

protocol Employer{   var employees : [Worker] {get set}}

Employer does not need to know or care of what it’s workers are, as long as they are working. Now, not only humans work, right? A robot could also conform to that protocol.

Without segregation

If we declared all Human functionality (One general purpose) and we wanted work() to be adopted by Robot, we would subclass Human and get some functionality we didn’t really want, like sleep(). Robots don’t sleep.
That’s why…:

“many client-specific interfaces are better than one general-purpose interface.”

Flexibility and reusability

We could declare a Sleeper protocol which can be adopted by both Cat and Human. Who knows if someday we’ll have a Bed struct which will have property like:

var currentSleeper : Sleeper

Interface segregation gives you the flexibility to do that.
It also gives you reusability at the same time, not to mention how it dances beautifully with the previous 3 principles we’ve been talking about.

Now for the last part Dependency Inversion Principle.

--

--