Catalog / SOLID Principles / Interface Segregation Principle (ISP)
SOLID

Interface Segregation Principle (ISP)

Clients should not be forced to depend upon interfaces that they do not use.

Intent & Objective

Prefer many small, focused, client-specific interfaces over one large, generalized, "fat" interface. Classes implementing an interface should never be forced to throw dummy or empty implementations for methods they do not need.

πŸ‘₯ Real-World Human Analogies & Social Roles
1 Intuitive Scenarios
Television Remote Control Consumer Appliances

"A TV viewer wants only Power, Volume, and Channel buttons, not an 80-button remote combining microwave and dishwasher controls."

The Problem

Fat interfaces force implementers to write hollow stub methods like `throw new UnsupportedOperationException()`. When one method in the fat interface changes, all implementers must recompile and test, even if they never invoked that method.

The Solution

Break down large interfaces into small, cohesive, role-based interfaces (e.g. `Printable`, `Scannable`, `Faxable` instead of `MultiFunctionDevice`).

Key Participants & Architectural Roles

Role Interfaces
Granular interfaces representing specific atomic capabilities
Client Implementations
Implement only the exact interfaces they actually support

Code Samples (Traditional OOP vs Functional Programming)

Available in C++, Python, and Java

Paradigm Contrast: Traditional OOP vs Functional / Data-Oriented

In OOP, ISP is solved using multiple inheritance of interfaces (e.g. implementing `Printer` and `Scanner` separately). In Functional Programming, ISP is inherently satisfied because functions take only the exact callback or value they need (e.g. passing a single `Consumer` or `Function`) instead of receiving a bloated interface.

Advantages

  • βœ“ Eliminates dead code and dummy exception-throwing stubs
  • βœ“ Enhances decoupling and makes components much easier to mock in tests
  • βœ“ Encourages composable, modular designs

Trade-offs

  • βœ— Can increase the total number of interface definitions

When to Apply

  • β†’ When an interface has methods that some implementers leave blank or throw `NotImplementedException`
  • β†’ When different clients of an interface consume completely disjoint subsets of its methods

When to Avoid

  • ! When every method in the interface is logically inseparable and needed by all consumers