Skip to main content

Interface Segregation Principle (ISP)

“Clients should not be forced to depend on methods they do not use.” In essence, large interfaces should be broken into smaller, role-specific interfaces so that implementing classes only need to know about the methods that matter to them.

Purpose:

  • Avoids “fat” interfaces – by splitting broad interfaces into focused ones, no class is burdened with irrelevant methods.
  • Reduces coupling and side effects: Changes to one part of an interface won’t impact classes that don’t use that part.
  • Makes implementations simpler and more flexible. A class can implement multiple small interfaces as needed, rather than one monolithic interface.

Minimal Example

Imagine a multi-function printer interface that includes printing, scanning, and faxing in one. A simple printer that only prints would still be forced to implement (or stub out) scan() and fax() methods, which it doesn’t need – violating ISP. Below, MultiFunctionDevice represents such a bloated interface and OldPrinter is needlessly forced to depend on unused methods. The solution is to segregate the interfaces: separate Printer, Scanner, and Fax interfaces so that classes implement only what they actually support.

More Realistic Example

Building on the printing example, we can have distinct interfaces and classes for each capability. For instance, PhotoPrinter implements Printer, OfficeScanner implements Scanner. A multi-function machine can be composed by combining a printer and a scanner implementation without any class having to implement methods it doesn’t use. This demonstrates how ISP enables flexible combinations of behaviors: