SOLID & DESIGN PRINCIPLES / OBJECT DESIGN BRIEF

Interface Segregation Principle

The Interface Segregation Principle (ISP) says clients should not be forced to depend on methods they do not use.

BeginnerPhase 02 / Topic 4 of 8ResponsibilitiesCollaborationsExtensibility
01

Overview

The Interface Segregation Principle (ISP) says clients should not be forced to depend on methods they do not use. Instead of one large interface, define several small, role-specific interfaces. A class can implement many of them; each client depends only on the role it needs.

Fat interfaces cause implementers to write empty or throwing methods, and cause clients to be recompiled or retested when unrelated methods change. ISP keeps contracts cohesive, makes fakes in tests tiny, and pairs naturally with LSP.

A universal remote with 80 buttons

Most people use five buttons. A simple remote for the TV and a separate one for the sound bar are easier to use, and replacing one does not affect the other.

02

When to use it

  • Implementations leave methods empty or throw UnsupportedOperationException.
  • Different clients use different subsets of an interface.
  • Test fakes need to implement many irrelevant methods.
03

Where it shows up in interviews

Fat interface refactoring

Recognize it when: Machine with print, scan, fax, staple.

  • Design a multifunction printer
  • Design a Worker interface for humans and robots
Role interfaces

Recognize it when: read-only clients vs writers.

  • Design a repository with readers and writers
  • Design an admin vs user API
04

Where it is used in real software

Java I/O

Readable, Closeable, Flushable, and AutoCloseable are tiny role interfaces combined as needed.

Go standard library

io.Reader and io.Writer are one-method interfaces; io.ReadWriter composes them.

CQRS

Separating command and query interfaces is ISP at the service level.

05

Key terms

Fat interface
Interface with many unrelated methods.
Role interface
Small interface representing one client's needs.
Interface composition
Combining small interfaces into larger ones where needed.
06

How it works, step by step

  1. 1
    List the clients

    Who calls this interface?

  2. 2
    Group methods by client usage

    Which methods does each client call?

  3. 3
    Extract role interfaces

    Printer, Scanner, Fax.

  4. 4
    Implement the relevant roles

    A basic printer implements only Printer.

  5. 5
    Clients depend on their role

    Not on the full implementation.

07

Splitting a Machine interface

interface Machine { print(); scan(); fax(); }

Step 1 / 4
DeviceWith fat MachineWith role interfaces
Basic printerscan() and fax() throwimplements Printer
Scannerprint() and fax() throwimplements Scanner
All-in-oneimplements everythingimplements Printer, Scanner, Fax
Print-queue clientdepends on scan and fax toodepends only on Printer

NOWDevice: Basic printer | With fat Machine: scan() and fax() throw | With role interfaces: implements Printer

No more throwing stubs, and each client sees only what it needs.

08

Implementation

interface Printer { print(doc: string): void }interface Scanner { scan(): string }interface Fax { fax(doc: string, number: string): void } class BasicPrinter implements Printer {  print(doc: string) { console.log("printing", doc); }} class OfficeMachine implements Printer, Scanner, Fax {  print(doc: string) { console.log("printing", doc); }  scan() { return "scanned-doc"; }  fax(doc: string, number: string) { console.log("faxing", doc, "to", number); }} // Client depends only on the role it usesclass PrintQueue {  constructor(private printer: Printer) {}  flush(docs: string[]) { docs.forEach((d) => this.printer.print(d)); }} new PrintQueue(new BasicPrinter()).flush(["a.pdf"]);new PrintQueue(new OfficeMachine()).flush(["b.pdf"]);
09

Complexity and performance

InterfacesMore, smaller

One per role.

Fake size in testsMinimal

Implement one role.

10

Trade-offs

Granularity

Too many one-method interfaces fragment the design; group methods that are always used together.

Discoverability

Many small interfaces require good naming and documentation.

11

Variants and related techniques

Interface composition

interface ReadWriter extends Reader, Writer.

Adapter per client

Wrap a large legacy API with narrow interfaces.

12

Common mistakes

  • Splitting by implementation rather than client needs.

    Fix: Design interfaces from the caller's perspective.

  • Header interfaces mirroring every public method of a class.

    Fix: Expose only what clients need.

13

Interview questions

How does ISP relate to LSP?

Fat interfaces force implementers to stub methods they cannot support, which breaks substitutability. Segregating interfaces lets each type implement only what it can honor.

Give an example of ISP in a real system.

Splitting a repository into reader and writer interfaces so reporting code gets read-only access, or Go's io.Reader and io.Writer used independently.

14

Practice problems

ProblemDifficultyWhat it trains
Split a Worker interface for humans and robotsEasyRoles.
Design interfaces for a smart home device hubMediumCapabilities.