Skip to main content
Category: Principles
Type: Systems design principle
Origin: Robert C. Martin, Engineering Notebook, C++ Report, 1996
Also known as: ISP; fat-interface problem; role interfaces
Quick Answer — The Interface Segregation Principle says clients should not be forced to depend on methods they do not use. Robert C. Martin named it in a 1996 C++ Report column after showing how a “fat” interface couples unrelated callers. The practical test is simple: if a change that you will never call still makes you rebuild, reread, or retest, the contract you depend on is too wide.

What is the Interface Segregation Principle?

The Interface Segregation Principle is a design rule that a caller should depend only on the methods it actually uses, not on a grab-bag contract that other callers happen to need.
Clients should not be forced to depend upon interfaces that they do not use.
That is not a plea for tiny classes. A single object may still do many jobs. The principle is about visibility: each client should see a slim, cohesive face, even if the object behind the faces is large. The everyday picture is a school trip form. A 20-minute museum visit does not need overnight medical consent, bank details, or a bus-driver certificate. If those fields sit on the same sheet, every parent must skip them—or mishandle them. When legal rewrites the overnight clause, the short-trip form reprints. The kitchen changed a dish nobody at that table ordered. In code, a “Worker” type that demands work(), eat(), and sleep() does the same thing to a robot. Empty methods, UnsupportedOperationException, and comments that say “do not call this here” are the bruise. The Single Responsibility Principle asks whether one module has too many reasons to change. This principle asks whether one client is being shown too many of those reasons.

Interface Segregation Principle in 3 Depths

  • Beginner: Do not hand someone a toolbox they will not open. If they only hang a picture, the corkscrew is not their problem—until a change to the corkscrew reissues the whole belt.
  • Practitioner: Split interfaces by who calls, not by who implements. Empty methods and “not supported” are the smell. A fat object may implement several thin faces.
  • Advanced: Clients push change backward onto the contracts they see. A fat interface therefore couples clients to each other. In a static language that is a recompile. At architecture scale it is still Martin’s later line: it is harmful to depend on a module that contains more than you need.

Origin

The Interface Segregation Principle began as a compile-and-coupling problem in statically typed object-oriented code, not as a slogan about “small interfaces.” Robert C. Martin stated it in The Interface Segregation Principle, the fourth of his Engineering Notebook columns for C++ Report (1996). The previous column (May 1996) had been the Dependency Inversion Principle. That column’s working line is the sentence quoted above. Martin’s target was the “fat” or “polluted” interface: a class whose methods fall into groups, each group serving a different set of clients. Some objects genuinely need a non-cohesive surface. Clients, he argued, should not have to know that surface as one type. The paper’s first wound is a security Door that can lock, unlock, and report open or closed. A TimedDoor also needs a timeout alarm, so designers push TimerClient onto Door. Timing-free doors then inherit a TimeOut method they must implement as a no-op. Worse, a fix to the timer—adding a timeout id so a door that closed and reopened does not alarm falsely—forces every client of Door to recompile. Martin’s diagnosis: separate clients mean separate interfaces. Nil virtuals on the parent also violate the Liskov Substitution Principle. The paper’s larger example is an ATM user interface. Deposit, withdrawal, and transfer each call a different slice of one UI type. A change that one transaction forces onto UI then hits every other transaction. The fix is DepositUI, WithdrawalUI, and TransferUI, which a concrete UI can multiply inherit. Wrapping those faces back into one header so callers “have everything in one place” recombines the coupling the split had removed. Martin restated the idea in Agile Software Development: Principles, Patterns, and Practices (Prentice Hall, 2003) as the companion slogan that many client-specific interfaces are better than one general-purpose interface. Around 2004, Michael Feathers arranged Martin’s “first five” principles into the SOLID mnemonic. The Interface Segregation Principle is the “I.” In Clean Architecture (Prentice Hall, 2017, Chapter 10) Martin widened the same warning beyond class files: it is harmful to depend on modules that contain more than you need. Martin Fowler’s role interface names the same cut from the caller’s side: an interface should describe a role a client needs, not the whole object it talks to. Later teaching often places the original consulting insight at Xerox, on a printer Job class that mixed print, staple, and fax. The 1996 paper itself does not name that client. The published exhibits are the timed door and the ATM UI.

Key Points

The Interface Segregation Principle earns its keep when several kinds of caller share one object and do not share the same methods. It is not a ban on rich objects. It is a rule about which methods you are not allowed to make a stranger compile against.
1

Clients push change backward onto what they see

We usually worry that a changed interface will break its users. Martin’s extra force runs the other way: a user can force a change onto an interface, and every other user of that fat type then pays. If payroll and the intern directory share one “employee portal” type, a tax-form field can make the intern app rebuild. Separation of concerns splits the jobs. This principle splits the windows onto those jobs.
2

Empty methods are a confession, not a design

A robot that implements eat() by throwing, or a bird that implements fly() as a no-op, is not “a specialized worker.” It is a child of an oversized parent. Those holes also fail substitutability: callers of the fat type cannot trust the method. Split the face so each implementer can honor every method it publishes.
3

Keep the fat object if you must; slim the faces

TimedDoor still has to talk to both doors and timers. Martin’s answers were an adapter object, or multiple inheritance of two slim bases. The same object can wear several hats. Callers should take one hat, not the whole rack. A club officer who is treasurer and key-holder can still exist. The snack rota should depend on “brings snacks,” not on the bank login.
4

Do not split methods that always travel together

One interface per method is not the goal. Methods that change for the same reason, and that the same callers always use together, belong on one face. YAGNI applies: do not invent a role until a second client actually needs a different slice. Over-segregation is a maze of types that still move as one.

Applications

Use the Interface Segregation Principle when one object or form serves several audiences, and a change for one audience should not land on the others. Do not use it to shatter a cohesive toolkit that every caller already uses whole.

Split the published face before the next caller arrives

If print jobs never staple, do not compile them against staple(). If a read-only report never saves, do not make it implement save(). Give each caller a role it can honor. The Open-Closed Principle then has a slot that new callers can fill without reopening old ones.

Write a job or volunteer role that a stand-in can actually hold

A “parent helper” sheet that demands a driving license, a food-hygiene certificate, and overnight medical consent will scare off the people who only bring cake. List the jobs the this rota must do, then ask only for those. A deputy who must skip half the form is not signed up. They are blocked by unused fields.

Print public forms as roles, not as one master packet

A short-stay visa, a library card, and a building-access pass should not share a single “any official request” PDF. Citizens pay the mismatch in extra visits and wrong attachments. If some applicants will never need a field, it does not belong on their parent form. Hide it by splitting the form, not by writing “skip if not applicable” in eight-point type.

Keep admin power off the everyday surface

An intern portal that loads payroll, board minutes, and production-kill switches violates the same rule as a fat type. Depend on the slice the role needs. That is least privilege applied to knowledge, not only to permissions. A change to the kill switch should not redeploy the intern homepage.

Case Study

The numbered window onto the Interface Segregation Principle as a public API is Java’s mouse event listeners—not a claim that one GUI package is the whole of coupling theory. JDK 1.1 (19 February 1997) replaced the old AWT inheritance event model with delegation: you implement a listener and register it. Mouse traffic was cut on purpose. MouseListener holds the five button-and-bound methods: mouseClicked, mousePressed, mouseReleased, mouseEntered, and mouseExited. MouseMotionListener holds the two motion methods: mouseMoved and mouseDragged. O’Reilly’s Java AWT Reference states the reason in numbers: the split lets you listen for clicks without being bothered by thousands of motion events. That cut is the principle working. Callers who never track motion do not depend on motion. The remaining click interface is still fat. Most teaching samples care about one of the five methods and leave the other four empty. The JDK’s own answer, also since 1.1, is MouseAdapter: an abstract class whose methods are empty, so you override only the events you care about. Oracle’s Java SE documentation still says so. As of Java SE 26 (2026), both the five-method interface and the adapter ship. WindowListener repeats the pattern with seven methods and a WindowAdapter. The adapter is a convenience, not a segregated contract. Clients still compile against a type that lists methods they will never call. If a sixth mouse method were added to MouseListener, every direct implementer would have to change. Java 8 (March 2014) added default methods, which could have put empty bodies on the interface itself. The published listener types were not redesigned around that. The lesson for new design is the 1997 motion cut, not the adapter patch: split by client need before you print empty methods. Boundary note: a drawing tool that must handle press, drag, and release together should keep those methods on one face. The failure is a contract that mixes unrelated audiences, not every interface with more than one method.

Boundaries and Failure Modes

The Interface Segregation Principle fails when the split is finer than the clients. If every caller always uses lock, unlock, and isOpen together, three one-method types add navigation without removing coupling. Those methods are one role. Leave them on one face. It also fails as a retrofit on a published fat type. MouseListener is the exhibit: the adapter papers over empty methods, and the right cut for button events was never taken. Calling a 1997 adapter “the pattern” does not make it safe to copy into a new API. Copy the motion/button split, not the five empty stubs. The common misuse is one interface per method, then a pile of types that still change as a set. That is ceremony, not segregation. Another misuse is treating this principle as a rename of the Single Responsibility Principle. Responsibility is about reasons a module changes. Segregation is about what a caller is forced to see. A module can have one reason to change and still show three unrelated callers the same fat window. Unexpected empty methods also fight fail fast: the program does fail, but at a call the fat type had advertised as ordinary.

Common Misconceptions

The English name collides with “make every interface one method,” with “only languages that have an interface keyword,” and with adapters as a substitute for a split.
Martin’s ATM split is by client, not by method count. Deposit needs a deposit face, which may have several deposit messages. Methods that the same callers always use together should stay together. A type with one method that nobody needed isolated is not a success. It is leftover dust from a gold-plating pass.
Martin’s 1996 column used C++ abstract classes because that was the magazine. The same shape appears in APIs, documents, portals, and job descriptions. If a slot says “any helper,” “any attachment,” or “any employee,” the stand-in should not have to carry fields or modules that the slot never uses. A microservice that imports a fat shared library for one function is the same failure without a class keyword.
Adapters and default methods reduce typing. They do not reduce the contract. Callers still depend on a type that lists methods they ignore, so a later addition still ripples. An empty body is a postponed split. If a role does not use the method, the role’s type should not mention the method.
These pages sit next to the same problem: how to let several audiences use one object or form without making each audience carry the others’ baggage.

Single Responsibility Principle

One reason to change per module. This principle asks which of those reasons a given caller is forced to see.

Liskov Substitution Principle

Empty or unsupported methods on a fat parent are substitution holes as well as segregation failures.

Open-Closed Principle

New callers should plug into a slim slot. A fat slot reopens old callers when the new one arrives.

Separation of Concerns

Keep different decisions apart. Segregation is how those decisions are shown to different clients.

YAGNI Principle

Do not invent a role until a second client needs a different slice. Over-splitting is speculative architecture.

Principle of Least Privilege

Depend only on the access you need. This principle is the same cut applied to methods and modules, not only to permissions.

One-Line Takeaway

If a caller must implement, import, or skip methods it will never use, the contract is too wide—split the face by role, and let the fat object wear more than one hat.