Wrap Up (3)
ISP in one honest sentence
The Interface Segregation Principle says: clients must not be forced to depend on methods they do not use. The senior mechanism is compile-time honesty: by narrowing the type a client holds to a role interface, impossible calls fail to compile instead of exploding at runtime as UnsupportedOperationException (or silent no-ops).
// Fat interface — client can call scan() on a printer that cannot scan
Machine m = new SimplePrinter();
m.scan(...); // compiles; throws at runtime (or no-ops)
// Role interfaces — wrong capability is unrepresentable
Printer p = new SimplePrinter();
// p.scan(...); // does not compile — SimplePrinter is not a Scanner
ISP moves wrong-capability use from a runtime surprise to a compile error by narrowing the type the client holds. That is the whole principle, not "make interfaces smaller for aesthetics."
Importance of ISP
- Prevents Bloated Classes: Smaller, role-focused interfaces ensure classes are not forced to implement methods they cannot honour.
- Improves Maintainability: Each role interface changes for one reason; clients that do not use that role are not recompiled.
- Enhances Flexibility: New capabilities arrive as new interfaces; existing implementers that do not need them stay untouched.
- Simplifies Testing: A fake only implements the role under test (e.g.
Printer), not an entire multi-function machine API. - Promotes Clearer Design: Role names document what a collaborator is allowed to demand.
How ISP Relates to Other SOLID Principles
- SRP: ISP supports SRP by keeping interfaces focused on a single role/actor, ensuring classes implement only what they need.
- OCP: ISP aligns with OCP by making it easy to extend systems with new role interfaces without modifying existing ones.
- LSP: ISP helps with LSP because classes implementing smaller interfaces respect their contract; they are never asked to "honour" methods they cannot implement.
ISP Takeaways
| Principle | Smell | Fix | When it hurts |
|---|---|---|---|
| Interface Segregation Principle | A fat interface forces implementers to provide no-op or throw-away implementations; clients see methods they never call; wrong calls only fail at runtime. | Split into role-specific interfaces. Clients depend only on the methods they actually use. Impossible calls become compile errors (compile-time honesty). | Fragmenting every method into its own interface creates noise. Keep methods that are always used together by the same client role in the same interface. |
When applying ISP hurts
- One-method-per-interface noise. If every client always needs print+scan+fax together, a single
OfficeMachineis honest; splitting is ceremony. - Framework SPI that is genuinely one role. A stable plugin contract used by a small set of implementers may stay "fat" if every method is required.
- Role explosion without client diversity. Segregate when clients differ; not when only the implementers differ but all clients use the full surface.
The call you defend
The tempting alternative to segregation is a single fat type plus a runtime guard — if (machine.canScan()) machine.scan();, or a supportsScan() flag. It compiles, it is one type, and it feels defensive. It is the wrong default for exactly the same reason the throwing stub is: it keeps the question "can this object scan?" alive until runtime, so a caller who forgets the guard ships a production bug instead of seeing a red squiggle in the editor. Role interfaces answer that question in the type system — a method that asks for Scanner simply cannot be handed a printer. Prefer the flag only when capability is genuinely dynamic (a device that gains or loses scanning while running), which is rare; when capability is fixed per class, the narrow type is strictly safer and costs nothing at runtime. That is the trade ISP is really making: pay one extra interface at design time to convert a whole class of runtime bugs into compile errors.
ISP → Design Patterns
Patterns that naturally produce segregated interfaces:
- Adapter — Lets a class expose only the subset of a fat interface that a client needs.
- Facade — Presents a simplified, focused interface over a complex subsystem.
- Strategy — Each strategy exposes exactly one method, the most segregated interface possible.
Follow-Up Drills
- Design a
Machineinterface with methods for print, scan, and fax. Then show how a simple printer is forced into a bad implementation. Refactor using ISP soscanis uncallable on the printer type at compile time. - When is a fat interface acceptable? Hint: think about framework-level abstractions used by a small, stable set of clients where every method is required.
- How does ISP make unit testing easier? Give a concrete example with a role interface vs mocking a 20-method service.
Before You Continue
ISP is the principle that protects clients from volatility they did not cause. A client should never be recompiled because a method it does not use changed. Internalize compile-time honesty, then move to DIP to see how dependencies should point.
🤖 Don't fully get this? Learn it with Claude
Stuck on Wrap Up (3)? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.
Build the mental picture, not memorization.
I just read a lesson on **Wrap Up (3)** (OO & Low-Level Design) and want to truly understand it. Explain Wrap Up (3) from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Socratic — adapts to where you're stuck.
Teach me **Wrap Up (3)** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Active recall exposes what you missed.
Quiz me on **Wrap Up (3)** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Intuition + hook + flashcards for long-term memory.
Help me remember **Wrap Up (3)** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.