Introduction
As your system grows, it is tempting to create one big interface or abstract class that “does everything” for a particular area.
Soon, different classes implement this interface but care only about a few of its methods, leaving the others empty or with dummy code.
The Interface Segregation Principle (ISP) exists to prevent this situation.
This article explains ISP in beginner‑friendly language, shows a “fat interface” example, and then walks through splitting it into smaller, more focused interfaces that better match each client's actual needs.
What Is the Interface Segregation Principle?
The Interface Segregation Principle says:
Clients should not be forced to depend on methods they do not use.In simpler words:
Do not design huge interfaces that try to satisfy every possible client.
Instead, create small, specific interfaces, so each client only depends on what it really needs.
You can think of ISP as:
“Many small menus are better than one giant menu full of dishes the customer will never order.”
Clients should not be aware of or affected by methods they do not care about.
ISP is about interface design, not just language “interfaces”—it also applies to abstract base classes used as contracts.
A “Fat Interface” That Violates ISP
Imagine you design a ReportService interface that tries to cover every possible operation for reports: class ReportService {
Now consider two different implementations:
A class that only needs to generate PDF reports and email them.
Another class that only needs to upload reports to FTP.
To satisfy the interface, each implementation must provide definitions for all methods, even ones it does not need.
Example of a class forced to implement unused methods:
Problems:
The class is forced to depend on Excel generation and FTP upload methods that it does not use.
It may end up with empty implementations or
throwstatements, which is ugly and risky.If you change something about Excel or FTP behavior in the interface, this class may be affected even though it does not care.
This violates ISP: the client (PdfEmailReportService) depends on methods it does not need.
Applying ISP: Split the Interface by Responsibilities
To follow ISP, you split the large interface into smaller, role‑based ones.
Step 1: Define Focused Interfaces
Each interface now represents a single capability:
Generating PDF.
Generating Excel.
Emailing reports.
Uploading to FTP.
Step 2: Implement Only What You Need
For a service that only cares about PDF and email:
For a service that only cares about uploading:
Now:
Each class only implements methods it truly needs.
No empty or fake implementations.
Changes to Excel or FTP behavior do not affect.
PdfEmailReportService.
This design respects ISP.
Realistic ISP Example: Read and Write Responsibilities
Another common example is a repository that both reads and writes data.
Fat Interface
Now imagine:
Some services only read users (e.g., reporting).
Some services only write users (e.g., user management tools).
You may also have read-only implementations (like a cached or snapshot repository).
These read‑only clients are forced to depend on saveUser deleteUser, which they never use.
Split Into Read and Write Interfaces
Now your implementations can choose:
A full repository implementing both:
A read‑only repository implementing only UserReader:
Clients that only read users depend on UserReader.
They are not forced to know anything about saving or deleting users, which matches the ISP.
How ISP Helps in LLD
ISP gives you clear benefits in Low-Level Design:
Reduced coupling for clients
Each client depends on only the methods it uses.
Changes in unrelated operations do not ripple into those clients.
Simpler implementations
Implementations are not cluttered with unnecessary methods.
Fewer chances of empty bodies or “not supported” exceptions.
Better testability
You can mock only the small interface a class depends on.
Tests are simpler because the contract is smaller.
Clearer responsibilities
Interfaces map closely to roles or capabilities, like
Notifier,PaymentMethod,UserReader,UserWriter.This also meshes well with the Single Responsibility Principle (SRP).
When you draw LLD class diagrams, you can show:
Smaller interfaces represent capabilities.
Concrete classes realize only the interfaces they actually support.
How to Spot ISP Violations
You might be violating the ISP if:
An interface has many methods that not all implementers care about.
You see lots of implementations with empty methods,
TODO, or “not supported” behavior.Changing the interface for one client breaks or touches many unrelated implementations.
The name of the interface sounds very generic and broad (like
Manager,Service,Handler) and its methods cover many unrelated responsibilities.
A good rule of thumb:
If you often say “This class only uses method X and Y from this interface,” then that interface might need to be split.
Summary
The Interface Segregation Principle says that clients should not be forced to depend on methods they do not use.
In practical terms, this means:
Avoid designing “fat” interfaces that try to serve every possible client.
Prefer several small, focused interfaces that each represent a clear capability.
Let classes implement only the interfaces—and therefore only the methods—that they actually need.
In this article, you learned:
The core idea of ISP in simple language.
A “fat interface” example with a reporting service and how to split it into focused interfaces.
A realistic read/write repository example where separating reading and writing interfaces helps.
How ISP improves coupling, implementation clarity, and testability in Low-Level Design.
How to recognize signs that an interface has grown too large and should be segregated.
Used together with SRP, OCP, and LSP, ISP helps you build cleaner abstractions where clients depend only on what they truly need.