Many Small Interfaces Instead of One Large Interface
The Interface Segregation Principle (ISP) states that no class should be forced to implement methods that it does not use.
“Clients should not be forced to depend upon interfaces that they do not use.” — Robert C. Martin
Simply put:
Many small, specialized interfaces are better than one large, general-purpose interface.
If a class implementing an interface is forced to define methods that make no sense for it, that is a sign that the interface is too broad and violates ISP.
Real-Life Example: How to Understand It?
Imagine you are a new employee signing an employment contract.
Instead of receiving a standard software developer contract, HR hands you an agreement that requires you to:
- write code,
- clean the office,
- conduct workplace safety training,
- work at the reception desk,
- repair the photocopier.
Of course, you could sign it, but what about the responsibilities that have nothing to do with your role?
What would you do with the clause about repairing photocopiers if you’ve never even touched one?
You would somehow need to handle it, most likely by leaving it blank or writing:
“Not applicable.”
And that is exactly where the problem begins.
The contract says you are responsible for something even though you do not actually do it.
Programming works the same way.
When a class implements an interface, it commits to providing implementations for all of its methods. If the interface is too broad, the class must somehow deal with methods that do not apply to it—typically by throwing an exception or leaving the method body empty.
That is an ISP violation.
Instead of one “contract for everything,” it is much better to have several specialized contracts:
- a contract for software developers (coding, code reviews),
- a contract for cleaning staff (cleaning and maintenance),
- a contract for receptionists (guest services and phone support).
Everyone signs only the contract that matches their actual responsibilities.
No sections are empty.
No obligations are fake.
A Thought Exercise
Let’s imagine a human resources system.
What happens if we create one generic Employee interface containing methods for every possible role?
Let’s look at the code.
Example — ISP Violation
Suppose we are building a factory workforce management system.
The factory has three types of workers:
- a production worker who operates machinery,
- a manager who attends meetings and manages teams,
- an industrial robot that performs manufacturing tasks but neither eats nor takes breaks.
In the first approach, we create a single interface for everyone:
Now let’s implement various worker types.
Production Worker
Industrial Robot
Manager
What’s Wrong with This Design?
Classes Throw Exceptions for Unsupported Methods
The Robot class implements takeLunchBreak(), but the only sensible thing it can do is throw an exception.
Anyone calling this method gets a runtime error instead of a compile-time indication that the operation is invalid.
The Interface Lies
When somebody sees:
Robot implements Employee
they naturally assume that a robot can do everything an Employee can do, including taking lunch breaks.
That assumption is false.
Changes Affect Everyone
Suppose we add:
void signUnionAgreement();
to the Employee interface.
Now every implementing class—including Robot—must provide an implementation, even though robots will never sign any agreement.
Example — ISP-Compliant Design
Let’s improve the design.
Instead of one large contract, we create several smaller interfaces, each describing a single capability.
Work Capability
Eating Capability
Management Capability
Now each class implements only the interfaces that actually apply to it.
Production Worker
Robot
Manager
What Did We Improve?
No More Unnecessary Exceptions
The Robot class does not have a takeLunchBreak() method.
Nobody can call it accidentally.
The error is impossible because the method does not exist.
Interfaces Are Honest
If a class implements Eatable, it can actually eat.
If it implements Workable, it can actually work.
The contract accurately reflects reality.
Changes Are Isolated
Adding a new method to Manageable affects only managers.
Robots and production workers remain untouched.
Composition Replaces a Monolith
Classes can implement any combination of interfaces.
Just like in real life, a person may fulfill multiple roles at the same time.
Why Is ISP Important?
Easier to Understand
A small interface with one or two methods clearly communicates its purpose.
Seeing:
implements Eatable
immediately tells us what the class can do.
Changes Are Safe and Isolated
When we extend Manageable, only classes implementing that interface are affected.
Unrelated classes remain untouched.
Simpler Testing
If a method depends on:
Workable
we can create a very small mock implementation containing only a single method.
There is no need to implement ten unused methods.
Better Team Collaboration
Narrow interfaces reduce merge conflicts.
Different developers can work independently on different interfaces without constantly interfering with one another.
Consequences of Ignoring ISP
Imagine an interface with 30 methods implemented by 20 classes.
Adding a single new method forces modifications to all 20 classes—even those that will never use it.
Developers often respond by adding:
and moving on, creating traps for future team members.
When Should You Apply ISP?
When Classes Leave Methods Empty or Throw Exceptions
This is the strongest signal of an ISP violation.
The class is essentially saying:
“I have to implement this, but it makes no sense for me.”
When Interface Changes Affect Unrelated Classes
If adding a method forces modifications in classes that will never use that method, the interface is too broad.
In APIs and Libraries
Spring Framework is an excellent example of ISP.
Instead of one large repository interface, Spring Data provides specialized interfaces:
CrudRepositoryPagingAndSortingRepositoryJpaRepository
Users choose only the level of functionality they actually need.
In E-Commerce Systems
Instead of a single Payment interface containing methods for cards, bank transfers, BLIK, and cryptocurrencies, it is better to create separate interfaces for each payment channel.
A BLIK implementation should not need to know anything about cryptocurrencies.
Memory Trick
Just as a doctor signs a doctor’s contract, not an agreement that also requires repairing cars, each specialist should have a contract tailored to their responsibilities.
A well-designed interface describes one coherent capability.
As a result:
- classes remain honest about what they can do,
- contracts remain meaningful,
- code becomes more predictable,
- systems become easier and safer to extend.

No responses yet