ISP Trade-offs: When to Use vs When It's Overkill
ISP improves flexibility and decoupling, but it is not free. Understanding when to apply ISP versus accepting a simpler unified interface requires analyzing your specific context.
When to Apply ISP
First, apply ISP when multiple distinct client types exist. If PayrollSystem, WorkScheduler, and HRPortal each use different subsets of an Employee interface, segregate it. Each client sees only what it needs.
Second, apply ISP when some implementations cannot meaningfully provide certain methods. A ReadOnlyFile cannot implement write(). Forcing it into a File interface with write() leads to runtime exceptions or no-op stubs, both harmful.
Third, apply ISP in plugin architectures where third-party implementations extend your system. Smaller interfaces lower the barrier to entry. A plugin author can implement Renderable without also implementing Serializable if those are segregated.
Fourth, apply ISP when interface changes are frequent in some areas but not others. Splitting a DocumentProcessor into Readable and Writable means changes to read logic do not force recompilation of write-only clients.
When ISP Is Overkill
Cohesive operations: If methods always appear together, keep them in one interface. A Stack with push(), pop(), and peek() should not be split. No client uses only push without pop. Splitting reduces clarity without adding flexibility.
Stable, narrow interfaces: An interface with two or three methods that rarely change and apply to all implementations does not need segregation. A Comparable interface with compareTo() is fine as-is. Over-segmentation creates interface proliferation without benefit.
Single implementation type: If only one class will ever implement the interface, ISP provides no value. The interface exists for polymorphism or dependency inversion, not to serve multiple clients. Premature segregation increases complexity.
Performance-critical tight coupling: In rare embedded or high-performance scenarios, interface dispatch overhead matters. If profiling shows that interface calls are a bottleneck and all clients need all methods anyway, a unified interface may be appropriate. But optimize only after measurement confirms the need.
ISP vs Alternatives
Cons: More interfaces to maintain, navigation complexity, potential over-engineering.
Use when: Multiple client types exist with distinct needs.
Cons: Clients see methods they do not use, implementers handle all methods.
Use when: Operations are cohesive and all clients need most methods.
Cons: Extra adapter classes, indirection overhead.
Use when: You cannot change the existing interface (third-party library).
Cons: Still one interface per facade, not fine-grained role segregation.
Use when: Clients need a simplified view of a complex subsystem, not role-based slices.
Decision Framework: Count distinct client types and their method usage. If Client A uses methods 1-3, Client B uses methods 4-6, and they never overlap, apply ISP. If most clients use 80% of methods, ISP adds little value.