Interface Segregation Principle (ISP)
Concept
The Interface Segregation Principle (ISP) states that no client should be forced to depend on methods it does not use.
Instead of creating massive, monolithic “fat” interfaces that contain dozens of methods, you should create multiple smaller, highly specific interfaces. This prevents classes from having to implement blank or dummy methods just to satisfy a bloated contract.
The Problem (Violation)
Imagine an interface for a smart multi-function printer:
interface MultiFunctionDevice {
print(doc: string): void;
scan(doc: string): void;
fax(doc: string): void;
}
class AdvancedPrinter implements MultiFunctionDevice {
print(doc: string) { /* ... */ }
scan(doc: string) { /* ... */ }
fax(doc: string) { /* ... */ }
}
Now, what happens if we buy a cheap, basic printer that only prints?
class BasicPrinter implements MultiFunctionDevice {
print(doc: string) {
console.log("Printing:", doc);
}
// Forced to implement methods it cannot perform!
scan(doc: string) {
throw new Error("Scan not supported");
}
fax(doc: string) {
throw new Error("Fax not supported");
}
}
BasicPrinter is forced to depend on scan and fax, forcing developers to write dummy error-throwing code. This violates ISP and also inherently violates the Liskov Substitution Principle (LSP).
The Solution
Segregate the massive interface into smaller, role-specific interfaces:
interface Printer {
print(doc: string): void;
}
interface Scanner {
scan(doc: string): void;
}
interface FaxMachine {
fax(doc: string): void;
}
Now, classes only implement exactly what they are capable of:
// The basic printer only implements Printer
class BasicPrinter implements Printer {
print(doc: string) {
console.log("Printing:", doc);
}
}
// The advanced device can compose multiple interfaces
class AdvancedPrinter implements Printer, Scanner, FaxMachine {
print(doc: string) { /* ... */ }
scan(doc: string) { /* ... */ }
fax(doc: string) { /* ... */ }
}
Real-World Use Case
In modern UI development (like React or Angular), passing a massive monolithic user object with 50 properties into a tiny Avatar component that only needs the profileImageUrl is an architectural violation similar to ISP. The component is forced to depend on data it doesn’t need. The solution is to pass exactly what the component requires as specific props.
Interview Questions
Q: How does ISP differ from the Single Responsibility Principle (SRP)?
A: SRP is about the implementation—ensuring a class or module only does one thing. ISP is about the contract—ensuring an interface only promises one cohesive set of behaviors. While closely related, ISP focuses heavily on the viewpoint of the client consuming the interface, ensuring it isn’t burdened with irrelevant dependencies.