Visual walkthrough — SOLID — Interface Segregation Principle
We start with nothing but two words. Let us earn them.
Step 1 — What an "interface" even is (a menu of promises)
WHAT. An interface is a list of things a piece of code promises it can do. Nothing more. It has no bodies, no logic — just names of abilities: work(), eat(), print(). Think of it as a menu: a printed list of dishes the kitchen swears it can cook.
WHY start here. Every later picture is about who is forced to sign this menu. If you don't picture the menu first, the word "depend" later means nothing.
PICTURE. On the left, a menu card listing three promises. On the right, a class — the "kitchen" — that must be able to deliver every line it signs.

Step 2 — The fat interface: one menu, forced on everyone
WHAT. A fat interface bundles unrelated promises into a single menu. Our running example is Worker, holding two unrelated abilities:
Here and are just the two names on the menu; the brace groups them into one interface called Worker.
WHY it looks fine. Both are things "a worker does", so lumping them feels natural — this is the trap.
PICTURE. One menu Worker with an arrow forcing it onto two very different signers: a Human (who genuinely eats) and a Robot (who does not). The robot is drawn in the accent colour — it is the problem child of every figure ahead.

Step 3 — Where it breaks: the forced lie
WHAT. Because the Robot signed the whole menu, it must provide a body for eat(). Having no notion of eating, it writes:
public void eat() { throw new UnsupportedOperationException(); }WHY this is a lie. The type Worker claims the robot can eat. The code inside admits it cannot. The compiler sees a satisfied menu and stays silent; the truth only explodes at runtime when someone actually calls robot.eat().
PICTURE. The robot's eat() slot filled with a red "bomb" — it compiles green but detonates when called. Contrast the human's honest, working eat().

Step 4 — The core rule, stated on the picture
WHAT. We can now read the principle straight off Step 3:
WHY the word "forced" is the whole point. The robot never asked for eat(); the menu forced it. Every ISP fix is just: remove the force.
PICTURE. The single fat arrow of Step 2, now labelled forced, with a red slash through it — the thing we are about to delete.

Step 5 — The fix: split by role, not by method
WHAT. Apply the parent's recipe: group methods by which clients use them together (their role), then make one interface per role.
Read this as: the two-promise menu becomes two one-role menus. Workable holds the working role; Feedable holds the eating role.
WHY split by role and not by every method. We split because work() and eat() serve different clients (a job scheduler vs. a canteen). We do not atomise blindly — if two methods were always used together by the same client, they'd stay in one interface. The dividing line is cohesion (see Cohesion and Coupling), not minimum size.
PICTURE. The fat Worker menu torn along the role seam into two clean cards.

Step 6 — Recompose: a class wears the roles it needs
WHAT. Now each class signs only the menus that describe it, and may sign several:
class HumanWorker implements Workable, Feedable { ... } // both roles
class RobotWorker implements Workable { ... } // one honest roleWHY this is honest. The robot's contract now says exactly what it can do — no eat(), no bomb, no lie. A canteen scheduler is written against Feedable; it cannot even name a RobotWorker, so the runtime bug of Step 3 becomes impossible to compile.
PICTURE. Human signs both cards; robot signs only Workable. The red robot is finally telling the truth — drawn without any bomb.

Step 7 — Measuring the win (the numbers, drawn)
WHAT. Let a fat interface have methods and implementers, where implementer genuinely uses of them. The forced (dead) dependencies are the gaps summed over everyone:
- — how many promises each implementer is forced to sign.
- — how many that implementer actually needs.
- — the dead weight for implementer (the red gap).
After perfect segregation each class pulls in exactly , so every gap is zero: .
WHY this formula. It turns "feels bloated" into a countable number, so you can see the improvement rather than argue about it.
Numbers (the printer example). (print/scan/fax), implementers use :
Four forced dependencies vanish under ISP.
PICTURE. A bar chart: for each of the three printers, the tall bar is ; the red slice on top is the forced gap . The red slices sum to 4.

Step 8 — The degenerate cases (so nothing surprises you)
WHAT & WHY. Check the edges of the formula so no scenario is left unshown:
| Case | Condition | Meaning | |
|---|---|---|---|
| Everyone uses everything | for all | Interface is already cohesive — do not split; that would be over-splitting (Step 5). | |
| Someone uses nothing | per such class | Maximum lie — the whole menu is dead weight for that class. | |
| One implementer, | any | Even a single class can suffer forced dependencies. | |
| After segregation | roles matched to need | The target state. |
PICTURE. Two extreme bars side by side: left, a cohesive interface (no red, leave it alone); right, a class using nothing (all red, the pure-lie case).

The one-picture summary
Everything on one card: the fat Worker menu (top) forces eat() onto a robot (the bomb), so we tear it along the role seam into Workable + Feedable (bottom), and the robot signs only what is true.

Recall Feynman retelling — the whole walkthrough in plain words
An interface is a menu of things code promises it can do. A fat menu (Worker) forces every signer to promise every dish — so a Robot, who cannot eat, still has to sign eat(). It fakes it with a stub that throws — a lie that compiles but explodes when called. The fix: tear the menu along its role seams — a work menu and an eat menu — and let each class sign only the menus that are honestly true of it. The Human signs both; the Robot signs only Workable, and now the eating-bug can't even be written. To prove the win we count forced dishes: each signer promises but needs only , so the wasted promises are — which becomes zero after we split. And the catch: only tear where waste actually shows up (where the bars turn red). If everyone already uses everything, leave the menu alone.
Connections
- SOLID — Single Responsibility Principle — one role per interface = one reason to change.
- SOLID — Liskov Substitution Principle — the stubbed
eat()bomb (Step 3) is an LSP break. - SOLID — Dependency Inversion Principle — depend on the small role menus, not the fat one.
- Cohesion and Coupling — the seam we tear along in Step 5 is cohesion.
- Design Patterns — Adapter — adapters bridge the segregated role interfaces.
- Back to parent: ISP index / Hinglish