A Algo3DVerse
I — Interface Segregation
SOLID — Principle 4 of 5

Interface Segregation
Principle

No client should be forced to depend on methods it does not use. Prefer many focused interfaces over one bloated interface.

Robert C. Martin's fourth principle: a "fat" interface forces every implementing class to stub out methods it doesn't need. Split large interfaces into smaller, role-specific ones so each client only depends on what it actually uses.

Watch it segregate

The large yellow ring is a fat interface. Red spokes show unused method connections. Press Segregate to split it into focused role interfaces.

drag — scroll to zoom

Code example

IWorker forcing a Robot to implement Eat(). Toggle to compare C# and JavaScript.

ISP VIOLATION ? FIX
// ? BAD — fat interface forces Robot to implement Eat() and Sleep()
public interface IWorker
{
    void Work();
    void Eat();   // robots don't eat!
    void Sleep(); // robots don't sleep!
}

public class Robot : IWorker
{
    public void Work()  { /* does work */ }
    public void Eat()   { throw new NotImplementedException(); } // forced stub!
    public void Sleep() { throw new NotImplementedException(); } // forced stub!
}

// ? GOOD — segregated into focused role interfaces
public interface IWorkable  { void Work(); }
public interface IEatable   { void Eat(); }
public interface ISleepable { void Sleep(); }

public class Human : IWorkable, IEatable, ISleepable
{
    public void Work()  { /* works */ }
    public void Eat()   { /* eats */ }
    public void Sleep() { /* sleeps */ }
}

public class Robot : IWorkable  // only what it needs
{
    public void Work() { /* works */ }
    // No forced stubs — no Eat, no Sleep
}
// ? BAD — one interface forces everything onto all implementors
class Robot {
    work()  { console.log('working'); }
    eat()   { throw new Error('Robots do not eat!'); } // forced!
    sleep() { throw new Error('Robots do not sleep!'); } // forced!
}

// ? GOOD — compose only the behaviours you need
// Role mixins (simulating interfaces in JS)
const Workable  = (Base) => class extends Base { work()  { console.log('working'); } };
const Eatable   = (Base) => class extends Base { eat()   { console.log('eating'); } };
const Sleepable = (Base) => class extends Base { sleep() { console.log('sleeping'); } };

class Human extends Workable(Eatable(Sleepable(Object))) {}
// Human: work ?  eat ?  sleep ?

class Robot extends Workable(Object) {}
// Robot: work ?  (no eat, no sleep — not forced)

const r = new Robot();
r.work();  // 'working' ?
// r.eat()  ? TypeError — method doesn't exist, as intended

Key concepts

✂

Interface Segregation

split — focus — lean

Many small, client-specific interfaces beat one general-purpose interface. Each client only imports what it needs.

🍖

Fat Interface

anti-pattern — forces stubs

An interface with too many methods forces clients to implement irrelevant methods as stubs or throws — a design smell and a test burden.

🎭

Role Interface

one role — one interface

Each interface represents a single role or capability: IWorkable, IEatable, ISleepable. Classes pick and choose what roles they play.

👤

Client-Specific Design

caller drives interface

Interfaces should be defined by what callers need, not by what implementations provide. Let usage shape the abstraction.

→ Liskov Substitution SOLID Principles — Algo3DVerse Dependency Inversion ?
Press ? to begin the narration walkthrough.
0 / 8