> ## Documentation Index
> Fetch the complete documentation index at: https://meta.niceshare.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Interface Segregation Principle

> Interface Segregation Principle says clients should not depend on methods they do not use. Origin, Java MouseListener, and limits.

<Info>
  **Category**: Principles<br />
  **Type**: Systems design principle<br />
  **Origin**: Robert C. Martin, Engineering Notebook, *C++ Report*, 1996<br />
  **Also known as**: ISP; fat-interface problem; role interfaces
</Info>

<Note>
  **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.
</Note>

## 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](/principles/single-responsibility) 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](/principles/liskov-substitution).

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.

<Steps>
  <Step title="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](/principles/separation-of-concerns) splits the jobs. This principle splits the *windows* onto those jobs.
  </Step>

  <Step title="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.
  </Step>

  <Step title="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.
  </Step>

  <Step title="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](/principles/yagni-principle) 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.
  </Step>
</Steps>

## 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.

<CardGroup cols={2}>
  <Card title="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](/principles/open-closed) then has a slot that new callers can fill without reopening old ones.
  </Card>

  <Card title="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.
  </Card>

  <Card title="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.
  </Card>

  <Card title="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](/principles/least-privilege) applied to knowledge, not only to permissions. A change to the kill switch should not redeploy the intern homepage.
  </Card>
</CardGroup>

## 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](/principles/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.

<AccordionGroup>
  <Accordion title="The Interface Segregation Principle means one method per interface">
    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.
  </Accordion>

  <Accordion title="The Interface Segregation Principle applies only to object-oriented interfaces">
    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.
  </Accordion>

  <Accordion title="Empty adapters and default methods make a fat interface acceptable">
    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.
  </Accordion>
</AccordionGroup>

## Related Concepts

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.

<CardGroup cols={3}>
  <Card title="Single Responsibility Principle" href="/principles/single-responsibility">One reason to change per module. This principle asks which of those reasons a given caller is forced to see.</Card>
  <Card title="Liskov Substitution Principle" href="/principles/liskov-substitution">Empty or unsupported methods on a fat parent are substitution holes as well as segregation failures.</Card>
  <Card title="Open-Closed Principle" href="/principles/open-closed">New callers should plug into a slim slot. A fat slot reopens old callers when the new one arrives.</Card>
  <Card title="Separation of Concerns" href="/principles/separation-of-concerns">Keep different decisions apart. Segregation is how those decisions are *shown* to different clients.</Card>
  <Card title="YAGNI Principle" href="/principles/yagni-principle">Do not invent a role until a second client needs a different slice. Over-splitting is speculative architecture.</Card>
  <Card title="Principle of Least Privilege" href="/principles/least-privilege">Depend only on the access you need. This principle is the same cut applied to methods and modules, not only to permissions.</Card>
</CardGroup>

## One-Line Takeaway

<Tip>
  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.
</Tip>
