SOLID — Interface Segregation

3 min readJun 11, 2024

In this article, we will discuss the Interface Segregation Principle. If you stumbled upon this article without any context, I recommend going back a few steps in the game and starting with the first article. After all, this article is about the fourth principle of SOLID. Before reading this article, it is essential that you are familiar with Single Responsibility, Open-Closed, and Liskov Substitution.

The principle

Interface Segregation is the principle that regulates programmers’ excesses. When we talk about DRY (Don’t Repeat Yourself) and other code organization principles, we tend to want to centralize things as much as possible and give them names, but we may unintentionally cause harmful excesses in the code. For example, by following the Liskov principle and creating an extremely broad and generic interface that encompasses more than it should. Liskov is meant to give us direction on maintainability and substituting items in a way that is backward compatible, inheriting structural similarities with items from higher layers. The issue is that it becomes easy to overdo it when following Liskov.

The roles of interface segregation go beyond abstraction and can actually be useful and save a lot of reprocessing if we think of languages like Java, where changing something in a module requires a rebuild of many different parts of it. By following the interface segregation principle, we regulate how generic interfaces are so that changing the interface of one module does not directly affect another module. A bit confusing, perhaps?

It is harmful to depend on modules that contain more elements than you need. The principle is actually quite simple. The book “Clean Architecture” by Robert Martin simplifies it with a fantastic example! Below you can see the image.

Suppose the database has unnecessary resources for the system, but at a certain point, they are updated and impact how the data organization works. We will automatically need to refactor the framework implementation, which will force us to change the system’s code, our core layer that should be untouched. Segregate things; do not leave them connected unnecessarily. The framework should not communicate directly with the database, and the system should not know the framework’s logic. By creating interfaces and layers separating them, it would be simple to resolve the database change since the change would be in the layer between the framework and the database or something similar.

But how does this work at a low level within interfaces? A class should not be forced to depend on interfaces it does not use. Instead, the principle suggests that interfaces should be specific and targeted to the clients that use them, avoiding “fat” interfaces that contain methods not used by all the classes that implement them. This promotes a more cohesive design, reducing coupling and making the code more flexible and easier to maintain since changes to an interface do not unnecessarily affect all the classes that implement it.

In summary, depending on something that contains unnecessary items can cause unexpected problems. Implement and use only what is really necessary and under control.

Agree? Disagree? Did you like it? Leave your contribution by liking or commenting :)

--

--

Leonardo Herdy Marinho
Leonardo Herdy Marinho

Written by Leonardo Herdy Marinho

I am a Master in computer science, senior software engineer (mobile focused), author, and curious.

No responses yet