SOLID: Interface Segregation Principle
TIL about the interface segregation principle, and how it promotes decoupling of classes in your code through the separation of methods in to role interfaces
.
The interface segregation principle
is the I
in SOLID, and as the name suggests it is concerned with the design of interfaces in your application.
The principle states that no client should be forced to depend on methods it does not use.
In complicated applications, it can be easy to lump a bunch of methods into a common interface that many clients use. This leads to tight coupling of clients to code that has no relevance to their function.
Consider a Duck
interface. It contains methods for quacking and eating (as ducks do).
Now consider implementing a few concrete Duck classes, like MallardDuck
and RubberDuck
, that both implement the Duck
interface.
Is it clear that we have an interface segregation problem here? A RubberDuck
doesn’t eat, but it is required to implement the eat method of the Duck interface which is irrelevant to its operation.
This creates unnecessary coupling between the eat method and classes that implement the interface which do not require eating. If the eat method changes in the interface, we will need to update all classes that implement Duck. This leads to more changes in our codebase, more testing for regressions, and slower deploy times.
The interface segregation principle would tell us to separate the eat
and quack
methods of the Duck
interface in to two different interfaces like so:
Now MallardDuck
can implement both Eatable
and Quackable
, while RubberDuck can just implement Quackable
. This only couples the RubberDuck
to the method that is relevant to it. If the definition of Eatable changes, we would only need to update MallardDuck
and could leave RubberDuck
alone!
Following the interface segregation principle strictly can lead to a ton of different role specific interfaces
in our code, which is definitely a tradeoff in readability / verbosity.
To me, it seems like the interface segregation has similar goals as the single responsibility principle, but in regards to interfaces instead of classes.
Interfaces should define a single role
that an object can play in your code. Designing a system in this way will isolate changes to the role to just the relevant objects, reducing the scope and potential impact of changes to the role.
Comments