Skip to content

Interface segregation principle

The SOLID rule that clients should not depend on interface methods they do not use — decompose a fat interface into role-specific ones sized to each consumer's usage footprint, so a contract change's blast radius is read off the boundary rather than the call graph.

Core Idea

The Interface Segregation Principle (ISP) — one of Robert Martin's SOLID principles — holds that clients should not be forced to depend on interface methods they do not use. The structural problem it targets is the fat interface: a single contract that bundles methods serving several distinct client roles, requiring every client to declare a dependency on the whole bundle even though each client uses only a slice of it. In a typed, compiled system, that declaration is not merely notional — it creates compile-time, link-time, and deployment-time coupling. When any method in the fat interface changes, every client that imports the interface must be recompiled and redeployed, regardless of whether it uses the changed method; in a continuous-delivery pipeline this forces unnecessary rebuilds and re-verification across the entire dependent graph.

The prescribed fix is to decompose the fat interface into role-specific interfaces, each shaped by the usage footprint of one coherent client type rather than by the convenience of the implementing class, and to have the implementing class implement whichever role interfaces apply to it. A Document class that can be saved, printed, translated, and spell-checked implements four separate interfaces — Saveable, Printable, Translatable, SpellCheckable — and the backup service, printer service, and translation service each import only the one they need. Changes to SpellCheckable now propagate only to clients that declared they need spell-check capability; the backup and printer services are structurally insulated. The principle is a specific application of information hiding (Parnas) and minimised coupling to the OO method-contract level: the granularity of the interface controls the blast radius of any change to it, and the right granularity is the client's footprint, not the implementer's.

Structural Signature

Sig role-phrases:

  • the fat interface — an over-broad contract bundling methods that serve several distinct client roles
  • the heterogeneous client set — the consumers, each using only a slice of the interface
  • the dependency declaration — the coupling channel: a client depends on the whole interface it declares, not merely the methods it calls
  • the compile/link/deploy coupling — the consequence in a typed, build-graphed system: any change to the interface forces rebuild and redeploy of every client that imports it
  • the consumer-footprint sizing rule — the prescribed granularity: shape each interface to one coherent client role's usage, never to the implementer's manifest
  • the role-specific split — the refactor decomposing the fat interface into focused contracts, with the implementing class implementing whichever roles apply
  • the blast-radius reduction — the structural payoff: a change propagates only to clients of the affected sub-interface, read off the contract boundary rather than traced through the dependency graph
  • the sibling discriminations — the boundaries that keep the right lever in view: ISP constrains the contract (one client role) while single-responsibility constrains the implementation (one reason to change), and ISP governs what a client must know about while least-privilege governs what it may do

What It Is Not

  • Not about the methods a client calls. The coupling ISP targets is the dependency declaration on the whole interface, not the subset of methods actually invoked. A backup service that never calls spell-check still recompiles when a spell-check signature moves, because its dependency surface is the interface's full signature — so the corrected question is "what must this client declare it knows about?", not "what does it call?"
  • Not a generic "keep interfaces small." The principle is not a preference for low method counts; it is a sizing rule keyed to one client role's usage footprint. An interface with three methods can still be a fat interface if those three serve unrelated roles, and a ten-method interface used by one coherent role is fine. The granularity is set by who needs the contract, not by counting methods.
  • Not the single-responsibility principle. SRP constrains the implementation — one reason to change per class; ISP constrains the contract — one client role per interface. The axes vary independently: a perfectly cohesive class can still expose a fat interface, so a cohesion fix will not contain a contract's blast radius. Conflating them sends the maintainer to the wrong lever.
  • Not least-privilege. Least-privilege governs what a client may do (access control); ISP governs what a client must know about (dependency declaration). They are dual but distinct — restricting a client's permissions does nothing to narrow the interface it is coupled to, and segregating the interface grants no new authority.
  • Not "shape the interface to the implementing class." That is exactly the category error ISP corrects. A Document genuinely can be saved, printed, translated, and spell-checked, but bundling all four because the implementer offers them mirrors the implementer's manifest, not any consumer's need. An interface is a service to its consumers; the boundary is drawn to the consumer's footprint.
  • Not a substrate-independent law of over-bundling. A job description bundling unrelated duties or a form asking irrelevant questions resembles ISP only in shape. The load-bearing mechanism — type-system-mediated compile/link/deploy coupling that forces a rebuild of a client coupled to a method it never invokes — does not exist in a hiring process or a paper form. Those problems are different in kind (cognitive overhead, friction) and fixed by different mechanisms; calling them "ISP" imports a compile-time pathology that substrate never had.

Scope of Application

ISP lives across the subfields of software design that share a typed contract whose declaration creates compile-, link-, or deploy-time coupling across a dependent build graph; its reach is within that domain. The surface analogues outside software (over-bundled job descriptions, over-broad forms) are metaphor — the load-bearing dependency-propagation mechanism is absent there — and the genuinely portable insight (minimize shared knowledge; size a boundary to the consumer's need) belongs to the parent interface, modularity, and information-hiding primes.

  • Object-oriented method contracts — the canonical home: splitting Readable/Writable/Seekable out of a fat File, or Comparable/Iterable/Cloneable out of a bundled capability set in Java/C#/C++/TypeScript.
  • RPC and REST API design — dividing endpoint surfaces by client persona (admin, user, external partner) rather than by implementation, decoupling client tiers from backend evolution.
  • GUI toolkits and component libraries — role interfaces (Focusable, Resizable, Themeable) so consumers depend only on the capabilities they exercise, rather than one giant Widget.
  • Plugin and extension architectures — focused per-event hooks (OnSave, OnLoad, OnChange) rather than one fat ExtensionPoint carrying every possible callback.
  • Trait and type-class design — Rust traits, Haskell type classes, and Scala mixins encouraging small role-specific contracts (Iterator, Display, Eq) for the same coupling reason in typed and functional languages.

Clarity

ISP makes legible a coupling that is invisible at the level of method calls: in a typed, compiled system a client is coupled to every method it declares a dependency on, not merely to the methods it invokes. Without the principle, a maintainer reasons about coupling by tracing call graphs and concludes the backup service is independent of the spell-check API because it never calls it — then is baffled when a spell-check signature change forces a recompile and redeploy of the backup service. ISP names the missing link: the client imports the whole fat interface, so its dependency surface is the interface's full signature, and the blast radius of any change is set by interface granularity rather than by who calls what. The sharper question a designer can now ask is not "which methods does this client call?" but "which contract does this client have to declare it knows about, and what gets dragged along when it does?"

The principle also sharpens a distinction that fat interfaces blur: whose needs an interface is for. A bundled contract usually mirrors the implementing class — a Document genuinely can be saved, printed, translated, and spell-checked, so the interface accretes all four — and ISP reframes that as a category error: an interface is a service to its consumers, shaped by one client role's usage footprint, not a manifest of what the implementer happens to do. This is what separates ISP from its SOLID siblings that get conflated with it. The single-responsibility principle constrains the implementation (one reason to change per class); ISP constrains the contract (one client role per interface), and the two vary independently — a cohesive class can still expose a fat interface. Least-privilege governs what a client may do; ISP governs what a client must know about. Holding "what the implementer offers" apart from "what each consumer must depend on" is the discrimination the principle installs, and it converts a vague preference for small interfaces into a concrete sizing rule: the right granularity is the client's footprint.

Manages Complexity

The question a maintainer dreads — if I change this method, what breaks? — is, in a system of fat interfaces, a case-by-case investigation with no shortcut: to bound the blast radius of a change one would have to walk the entire dependent graph, and even a careful call-graph trace gives the wrong answer, because the coupling that forces a rebuild is the dependency declaration on the whole interface, not the subset of methods actually invoked. The backup service that never calls spell-check still recompiles when a spell-check signature moves. ISP collapses that intractable, per-change graph walk into a single readable quantity: interface granularity. Once each interface is sized to one client role's usage footprint, the blast radius of any change is no longer something to be discovered by tracing — it is simply the set of clients of the affected sub-interface, read directly off the interface boundary. A change to SpellCheckable touches spell-check clients and no one else; the maintainer reads the propagation off the contract's shape instead of re-deriving it from the dependency graph each time. The principle compresses the sprawl of "which clients are coupled to which methods, and by what kind of coupling" down to one design parameter the analyst can hold and tune. It also installs a clean discrimination that keeps the parameter trustworthy: what the implementer offers versus what each consumer must declare it depends on — the right granularity is the consumer's footprint, never the implementer's manifest. And it sharpens a branch that fat interfaces blur and that the SOLID siblings get conflated over: a contract change is contained to one client role (ISP, contract granularity) or one implementation has one reason to change (single-responsibility, implementation cohesion) — independent axes, so a perfectly cohesive class can still leak a fat interface. With the granularity parameter set to the footprint, change-propagation, build cost, test surface, and the cost of replacing the interface all follow from where the boundaries were drawn, so the designer reasons about the qualitative cost of a contract from its sizing rule rather than from a fresh impact analysis at every edit.

Abstract Reasoning

ISP licenses a set of reasoning moves in object-oriented and typed-API design, all turning on the parameter it installs — interface granularity sized to the client's footprint — and on the coupling channel it exposes: a client depends on what it declares, not on what it calls.

The diagnostic move runs from a surface symptom to the structural cause. When a maintainer observes that an unrelated client recompiles and redeploys after a change to a method it never invokes — the backup service rebuilt by a spell-check signature change — the principle names the hidden coupling: the client imported the whole fat interface, so its dependency surface is the interface's full signature and the change's blast radius is set by interface granularity, not by the call graph. The reasoner infers the presence of a fat interface from the symptom of spurious rebuilds, and conversely predicts those rebuilds whenever heterogeneous clients share one bundled contract. The corrected diagnostic question is not "which methods does this client call?" but "which contract must this client declare it knows about, and what gets dragged along when it does?"

The predictive move reads change-propagation off the contract's shape. Given a system already segregated into role interfaces, the blast radius of a change is no longer something to be traced through the dependency graph — it is exactly the set of clients of the affected sub-interface, read directly off the interface boundary. A change to SpellCheckable will touch spell-check clients and no others; build cost, test surface, and re-verification scope all follow from where the boundaries were drawn. The reasoner forecasts the qualitative cost of a contract change from its granularity, before making the edit.

The interventionist move is the prescribed refactor with its predicted effect: decompose the fat interface into role-specific interfaces, each shaped by one coherent client role's usage footprint, and have the implementing class implement whichever roles apply. The predicted effect is structural insulation — changes to one role propagate only to that role's clients, and the previously-coupled services become independent at compile, link, and deploy time. The intervention's sizing rule is definite: draw each boundary to the consumer's footprint, never to the implementer's manifest, because the right granularity is set by who needs the contract, not by what the class happens to do.

The boundary-drawing move fixes when ISP's mechanism actually bites and separates it from siblings it is conflated with. The dependency-propagation pathology is real where declaring a contract creates compile-, link-, or deploy-time coupling — typed, compiled software with a dependent build graph; it is the load-bearing channel, so the analysis is keyed to that substrate, not to mere "too many methods." Within design it discriminates independent axes: ISP constrains the contract (one client role per interface), the single-responsibility principle constrains the implementation (one reason to change per class), and the two vary independently — a perfectly cohesive class can still expose a fat interface, so a cohesion fix will not contain a contract's blast radius and only resizing the interface will. Least-privilege governs what a client may do; ISP governs what a client must know about. Holding "what the implementer offers" apart from "what each consumer must depend on" is the discrimination that decides which lever to pull when something over-couples.

Knowledge Transfer

Within software design ISP transfers as mechanism. The diagnostic (read spurious rebuilds of a client that never calls the changed method back to a fat interface, recognizing that the coupling channel is the dependency declaration, not the call graph), the sizing rule (draw each interface to the consumer's usage footprint, never the implementer's manifest), the blast-radius prediction read off interface granularity, and the discriminations that keep the lever trustworthy (ISP constrains the contract, single-responsibility the implementation; ISP governs what a client must know about, least-privilege what it may do) carry intact wherever a contract is shared between an implementer and multiple client roles in a typed, build-graphed system. They apply unchanged to object-oriented method contracts (splitting Readable/Writable/Seekable out of a fat File), to RPC and REST API surfaces divided by client persona (admin/user/partner) rather than by implementation, to GUI component libraries (Focusable, Resizable, Themeable rather than one giant Widget), to plugin and extension architectures (focused OnSave/OnLoad/OnChange hooks rather than one ExtensionPoint), and to trait/type-class design in typed and functional languages (Rust traits, Haskell type classes, Scala mixins — small role-specific contracts like Iterator, Display, Eq). The transfer is mechanical here because each of these is the same substrate — typed contracts whose declaration creates compile-, link-, or deploy-time coupling across a dependent graph — so the dependency-propagation pathology and its granularity remedy refer to the same machinery throughout.

Beyond typed software the transfer is genuinely mixed, and the honest reading separates two layers. At the surface, ISP has loose analogues — a job description bundling unrelated duties forces every applicant to demonstrate all of them; a regulatory form asking irrelevant questions forces every respondent to gather the answers; a UI exposing every action forces every user to filter through them. These are case (A) metaphor: they borrow ISP's shape (over-bundling is bad; split by role) but the load-bearing mechanism — type-system-mediated dependency propagation that forces a rebuild of a client coupled to a method it never invokes — simply does not exist in a hiring process or a paper form, and the analogous problems there are different in kind (cognitive overhead, irrelevant work, friction) and are fixed by different mechanisms (role-specific recruiting, conditional form logic, progressive disclosure) that share the spirit but not the structural skeleton. Calling those "ISP" imports a compile-time pathology those substrates never had. Underneath the metaphor, though, there is a real case (B) component: the substrate-independent insight ISP encodes — minimize the shared knowledge between components, and size a boundary to the consumer's need rather than the implementer's convenience — does recur across systems engineering wherever module boundaries are drawn, and it travels as the parent primes ISP instantiates: interface (a bounded, rule-governed surface), modularity (boundaries placed to reduce coupling), and the need_to_know / information-hiding discipline (Parnas). ISP is precisely what those parents jointly prescribe when applied to object-oriented method contracts — a specific design tactic, not a new prime, and the same is true of its SOLID siblings and the dozens of named OO principles (Demeter, Hollywood, Open-Closed), each a software-substrate application of broader structural primes the catalogue already holds. So the honest cross-domain lesson is to carry those parents (minimize shared knowledge; align boundaries with usage), not "the interface segregation principle," whose defining content — dependency declaration creating compile/link/deploy coupling — is typed-software machinery that does not and should not travel. (See Structural Core vs. Domain Accent.)

Examples

Canonical

Robert C. Martin distilled ISP in the mid-1990s while consulting on a Xerox next-generation printer whose control software had grown a single fat Job class that nearly every task depended on — print jobs, staple jobs, cover-page jobs, and more. Because all tasks imported Job, a change to the staple-related methods forced a recompile and redeploy of unrelated tasks that never touched stapling, and build-and-verify cycles ballooned. Martin's fix was to interpose role-specific interfaces — StapleJob, PrintJob, and the rest — each carrying only the operations one client role used, with the concrete Job implementing all of them. A staple task then depended only on StapleJob, so staple-method changes propagated only to staple clients. He generalized the episode into ISP in Agile Software Development, Principles, Patterns, and Practices (2002).

Mapped back: The single Job class is the fat interface; the print, staple, and cover-page tasks are the heterogeneous client set, each using only one slice. Every task importing Job is the dependency declaration, creating exactly the compile/link/deploy coupling that produced the spurious recompiles. Carving StapleJob/PrintJob to each task's usage is the role-specific split under the consumer-footprint sizing rule, and the containment of staple-method changes to staple clients alone is the blast-radius reduction.

Applied / In Practice

The Go standard library codifies ISP in its io package, whose interfaces are deliberately tiny: Reader declares one method (Read), Writer one (Write), and Closer one (Close), with composites like ReadWriteCloser assembled only where a client genuinely needs all three. Rob Pike's maxim — "the bigger the interface, the weaker the abstraction" — is the sizing discipline in aphorism form. A function that only consumes bytes takes an io.Reader, so it couples to nothing but Read; a network socket, an open file, and an in-memory buffer all satisfy it without dragging in write or seek semantics. Code typed against io.Reader is thus insulated from changes to a concrete type's seek or write behaviour, because it never declared a dependency on those methods.

Mapped back: A hypothetical monolithic Stream contract would be the fat interface; readers, writers, and closers are the heterogeneous client set. Typing a parameter as io.Reader is the dependency declaration narrowed to a single method, so seek- or write-behaviour changes fall outside its blast-radius reduction. Go's one-method interfaces are the role-specific split sized by consumer footprint — Pike's "bigger interface, weaker abstraction" states that sizing rule directly.

Structural Tensions

T1: Consumer footprint versus implementer manifest (whose need shapes the boundary). ISP's sizing rule is that an interface is drawn to one client role's usage, never to what the implementing class happens to offer — yet the path of least resistance runs the other way, because a Document genuinely can be saved, printed, translated, and spell-checked, so the contract accretes all four by simply mirroring the class. The tension is that the natural, discoverable boundary (the implementer's manifest) is exactly the wrong one, while the correct boundary (the consumer's footprint) is invisible until one enumerates the clients and their distinct roles. A designer who shapes to the implementer gets a fat interface that compiles and runs correctly, so nothing forces the correction until a change's blast radius surprises someone downstream. Diagnostic: Was this interface's method set chosen by asking what one client role needs, or by cataloguing what the implementing class can do?

T2: Declaration coupling versus call coupling (where the substrate hides the dependency). The coupling ISP targets is the dependency a client declares, not the methods it calls — the backup service that never invokes spell-check still recompiles when a spell-check signature moves. This is the principle's sharpest insight and its narrowest precondition at once: the channel is real only where declaring a contract creates compile-, link-, or deploy-time coupling across a dependent build graph. In a dynamically typed or late-bound system with no such declaration, the call graph is the coupling, and ISP's central discrimination loses its teeth. The tension is that the very feature that makes ISP non-obvious and valuable — declaration outranks invocation — is exactly what binds it to one substrate, so the analysis keys to typed compiled software rather than to "too many methods" in general. Diagnostic: In this system, does merely declaring the interface force a rebuild, or is coupling incurred only when a method is actually called?

T3: Segregation versus proliferation (how fine is too fine). Decomposing a fat interface shrinks blast radius, and the footprint rule licenses splitting all the way to Go's one-method Reader/Writer/Closer. But the rule states a lower bound on cohesion, not an upper bound on count: nothing in ISP says when further splitting stops paying, and a system carved into dozens of micro-interfaces trades change-propagation cost for composition overhead, naming burden, and the boilerplate of implementing and assembling many contracts. The tension is that the principle's own logic — smaller footprint, smaller blast radius — pushes monotonically toward fragmentation, while usability pushes back, and ISP supplies the direction without the stopping point. Diagnostic: Does splitting this interface further reduce a blast radius some real client actually suffers, or only multiply contracts no divergent role needs?

T4: The right lever versus the conflated siblings (which principle is failing). ISP is routinely fused with the SOLID principles adjacent to it, and the fusion sends a maintainer to the wrong repair. SRP constrains the implementation (one reason to change per class); ISP constrains the contract (one client role per interface); least-privilege governs what a client may do while ISP governs what it must know about. Because a perfectly cohesive class can still expose a fat interface, a cohesion fix will not contain a contract's blast radius — only resizing the interface will. The tension is that these axes vary independently yet share the surface vocabulary of "keep things small and focused," so the diagnosis of which over-coupling is present is a real discrimination, not a restatement. Diagnostic: Is the over-coupling here about what one class must change for (SRP), what a client may do (least-privilege), or what a client must declare it depends on (ISP)?

T5: Boundaries fixed to today's footprint versus an evolving client set (static rule, moving target). ISP sizes each interface to the usage footprint of the coherent client roles that exist now, and reads blast radius directly off that boundary. But the footprint is a snapshot: a new client arriving with a genuinely new usage pattern either forces a fresh role-specific split or gets bolted onto an existing interface, re-fattening it. The tension is that the principle promises the blast radius can be "read off the contract boundary rather than traced through the graph," yet that guarantee holds only while the boundaries still match the live set of roles — segregation is not a one-time refactor but a standing obligation to re-segregate as consumers diverge. Diagnostic: Do the current interface boundaries still match the actual roles among today's clients, or has consumer drift quietly turned a once-segregated contract back into a fat one?

T6: Autonomy versus reduction (a named SOLID principle or an instance of its parents). "Interface segregation principle" is a canonically named, separately teachable OO design rule with its own origin story (Martin's Xerox printer Job class) and its own tactics. Yet its portable content is not proprietary: within typed software it travels intact across method contracts, RPC surfaces, GUI toolkits, and trait design, but beyond typed software it does not travel as mechanism at all — a fat job description or an over-broad form resembles it only in shape. What carries there is the more-general parents it instantiates: interface (a bounded surface), modularity (boundaries placed to reduce coupling), and need_to_know / information-hiding (Parnas). The tension is between a standalone principle worth naming and studying and the recognition that its cross-domain cargo already belongs to those parents. Diagnostic: Resolve toward the parents (interface, modularity, need-to-know) when asking what travels outside typed software; toward the named principle when diagnosing a contract's blast radius in a real build graph.

Structural–Framed Character

The interface segregation principle sits at framed-leaning — a named, prescriptive software-design rule well toward the framed side, whose reach beyond typed software is, by the entry's own account, metaphor rather than mechanism. On evaluative_weight it is framed: ISP is literally a principle, an "ought" ("clients should not be forced to depend on methods they do not use"), so it carries prescriptive force rather than describing a neutral mechanism — it tells a designer what to do, not merely what is. On human_practice_bound it is firmly framed: the pathology it targets is constituted by the practice of typed software design — it presupposes typed contracts whose declaration creates compile-, link-, or deploy-time coupling across a dependent build graph, and it dissolves entirely in a substrate (a hiring process, a paper form) that has no such build-time propagation. On institutional_origin it is framed: ISP is one of Martin's SOLID principles, with its own origin story (the Xerox printer Job class) and its own tactics — furniture of an object-oriented design tradition, one of dozens of named principles (Demeter, Hollywood, Open-Closed) that are software-substrate applications of broader structural ideas. On vocab_travels it is low: within typed software the diagnostic, the sizing rule, and the blast-radius prediction carry intact across method contracts, RPC surfaces, GUI toolkits, and trait design, but beyond typed software it "does not travel as mechanism at all," and the portable insight passes to the parent primes. On import_vs_recognize it is framed: the extra-domain analogues (an over-bundled job description, an over-broad form) borrow ISP's shape while the load-bearing dependency-propagation mechanism is absent, so they are metaphor, not recognition of the same mechanism.

The portable structural skeleton is minimize the shared knowledge between components and size a boundary to the consumer's need rather than the implementer's convenience. That skeleton is what ISP instantiates from its parent primes — interface (a bounded, rule-governed surface), modularity (boundaries placed to reduce coupling), and need_to_know / information-hiding (Parnas) — and it is those parents, jointly, that carry the cross-domain lesson; the domain-accented specifics that stay home are exactly ISP's defining content — dependency declaration (not invocation) creating compile/link/deploy coupling, the blast-radius-read-off-the-boundary payoff, and the SOLID-sibling discriminations against single-responsibility and least-privilege — none of which survive extraction to a substrate without a typed build graph. Its character: a prescriptive, named SOLID design rule whose defining content is typed-software machinery that travels only by metaphor, structural only in the minimize-shared-knowledge / size-boundaries-to-the-consumer insight it instantiates from its interface, modularity, and need-to-know parents.

Structural Core vs. Domain Accent

This section decides why the interface segregation principle is a domain-specific abstraction and not a prime — a case where a genuinely portable modularity insight sits beneath a defining mechanism that is pure typed-software machinery, so almost nothing but the insight survives extraction.

What is skeletal (could lift toward a cross-domain prime). Strip the type system and a portable insight survives: minimize the shared knowledge between components, and size a boundary to the consumer's need rather than the implementer's convenience. The portable pieces are abstract — a surface between a provider and its consumers, a cost to depending on more of that surface than one uses, and a rule that the boundary should be drawn to each consumer's usage rather than to the provider's manifest. This insight is genuinely substrate-portable — it recurs wherever module boundaries are drawn in systems engineering — and it is what the entry names as its parents: interface (a bounded, rule-governed surface), modularity (boundaries placed to reduce coupling), and need_to_know / information-hiding (Parnas). But this minimize-shared-knowledge insight is the core ISP shares with every well-drawn boundary, not what makes ISP distinctive.

What is domain-bound. Everything with defining content is typed-software machinery that does not survive extraction. ISP's central and non-obvious claim — that the coupling channel is the dependency declaration, not the methods actually called, so a client rebuilds when a method it never invokes changes — presupposes a typed, compiled system with a dependent build graph in which declaring a contract creates compile-, link-, or deploy-time coupling. The blast-radius-read-off-the-boundary payoff, the consumer-footprint sizing rule as a refactor of method contracts, and the SOLID-sibling discriminations (against single-responsibility's implementation-cohesion axis and least-privilege's access axis) are all furniture of object-oriented design. The decisive test: carry the concept to an over-bundled job description or an over-broad form and the load-bearing mechanism is simply absent — there is no build-time propagation, no rebuild forced by an un-invoked method; the analogous problems there are different in kind (cognitive overhead, friction, irrelevant work) and are fixed by different mechanisms (role-specific recruiting, conditional form logic, progressive disclosure). Calling those "ISP" imports a compile-time pathology the substrate never had.

Why this does not clear the prime bar. A prime's vocabulary travels and its transfer is recognition of the same mechanism, not analogy. ISP's transfer is bimodal. Within typed software it travels as mechanism — the fat-interface diagnostic, the sizing rule, the blast-radius prediction, and the sibling discriminations carry intact across method contracts, RPC/REST surfaces divided by client persona, GUI role interfaces, plugin hooks, and trait/type-class design, because those are one substrate (typed contracts whose declaration creates build-graph coupling). Beyond typed software it does not travel as mechanism at all: the surface analogues borrow ISP's shape while the dependency-propagation channel is absent, so they are metaphor. That is the prime-bar verdict: when the bare structural lesson (minimize shared knowledge; align boundaries with usage) is needed cross-domain, it is already carried, in more general form, by the parents ISP instantiates — interface, modularity, and need_to_know. The cross-domain reach belongs to those parents; "interface segregation principle," as named, carries dependency-declaration-creating-compile/link/deploy-coupling machinery that should stay home — and, like its SOLID siblings (Demeter, Hollywood, Open-Closed) and the dozens of named OO principles, is best read as a software-substrate application of broader structural primes the catalogue already holds, not a prime in its own right.

Relationships to Other Abstractions

Local relationship map for Interface segregation principleParents appear above the current abstraction, mutual partners to the right, and children below. Node labels state whether each abstraction is prime or domain-specific; colors identify relation types.Interfacesegregation principleDOMAINPrime abstraction: Interface — presupposesInterfacePRIMEPrime abstraction: Modularity — is a decomposition ofModularityPRIME

Current abstraction Interface segregation principle Domain-specific

Parents (2) — more general patterns this builds on

  • Interface segregation principle presupposes Interface Prime

    Interface segregation presupposes a rule-governed dependency surface whose exposed contract can be compared with each client's actual use.

  • Interface segregation principle is a decomposition of Modularity Prime

    ISP is modular decomposition applied to a contract surface, partitioning a fat interface into independently changing role-sized units.

Hierarchy paths (2) — routes to 2 parentless roots

Not to Be Confused With

  • The single-responsibility principle (SRP). The sibling SOLID rule that constrains the implementation — one reason to change per class — whereas ISP constrains the contract — one client role per interface. The axes vary independently: a perfectly cohesive class can still expose a fat interface, so a cohesion fix will not contain a contract's blast radius. Tell: is the over-coupling about what one class must change for (SRP), or what a client must declare it depends on (ISP)?

  • Least-privilege. The dual-but-distinct principle governing what a client may do (access control / authority), where ISP governs what a client must know about (dependency declaration). Restricting permissions does nothing to narrow the interface a client is coupled to, and segregating the interface grants no new authority. Tell: is the concern the client's permissions to act (least-privilege) or its compile-time knowledge surface (ISP)?

  • The generic "keep interfaces small" heuristic. A preference for low method counts. ISP is not that: it is a sizing rule keyed to one client role's usage footprint. A three-method interface serving unrelated roles is still fat; a ten-method interface used by one coherent role is fine. Tell: is the interface judged by counting methods (the heuristic) or by whether its methods serve a single client role (ISP)?

  • Other SOLID / OO principles (Open-Closed, Dependency Inversion, Liskov, Law of Demeter, Hollywood). Sibling named design rules in the same tradition, each targeting a different structural concern (extension without modification, depending on abstractions, subtype substitutability, minimizing acquaintance, inversion of control). They share ISP's spirit and vocabulary of "small, focused, decoupled" but not its specific mechanism — dependency-declaration-driven build coupling. Tell: does the rule concern interface granularity sized to the consumer (ISP), or a different coupling/extension concern the sibling names?

  • Non-software over-bundling (a job description, an over-broad form, a cluttered UI). The analogy case — an over-bundled job description or a form asking irrelevant questions resembles ISP in shape (split by role) but lacks the load-bearing mechanism: type-system-mediated compile/link/deploy coupling that forces a rebuild of a client coupled to a method it never invokes. Those problems are different in kind (cognitive overhead, friction) and fixed by different means (role-specific recruiting, conditional form logic). Tell: does merely declaring the contract force a rebuild across a build graph (ISP proper), or is the cost only human attention and effort (analogy — carry the parent primes, not "ISP")?

  • Interface / modularity / need-to-know (the parents). The substrate-neutral primes ISP instantiates — a bounded rule-governed surface, boundaries placed to reduce coupling, and information-hiding (Parnas). These jointly carry the portable insight (minimize shared knowledge; size a boundary to the consumer's need) across every substrate where boundaries are drawn. Tell: strip the typed build graph and what travels cross-domain is this parent bundle, treated more fully in a later section — ISP's compile-time machinery stays in typed software.

Neighborhood in Abstraction Space

Interface segregation principle sits in a crowded region of the domain-specific corpus (38th percentile for distinctiveness): several abstractions share nearly its structure, so a description that fits it tends to fit its neighbors too.

Family — Software Evolution & Systemic Laws (16 abstractions)

Nearest neighbors

Computed from structural-signature embeddings · 2026-07-12