Skip to content

Interface Segregation Principle

An interface is a list of methods that one piece of code offers to another. The Interface Segregation Principle (ISP) has one rule: no code should be forced to depend on methods it does not use. When an interface is large, the fix is to split it into smaller, role-specific interfaces.

Where the idea came from. Robert C. Martin formulated ISP while consulting for Xerox. Xerox had built a new printer system that could do many tasks, such as stapling and faxing. A single Job class grew into a “fat” class. It held many methods, each meant for a different client. Every client was therefore tied to methods it never used.

What a role interface is. A role interface is defined by one specific interaction between a supplier (the code that offers methods) and its consumers (the code that calls them). Classes often use only some of a supplier’s methods. A role interface shows which methods a consumer actually needs.

The opposite: the header interface. A header interface copies all public methods of a class into one interface. This is the reverse of a role interface.

Who should shape the interface. Required interfaces are specified, and often defined, by the client. Interfaces defined from the client’s perspective are more useful. That view leads toward role interfaces. For related terms, see Provided and Required Interface and UML Interface.

A reporting tool and a billing tool both call one CustomerService interface. It offers getName, getAddress, changeAddress, closeAccount and exportAll. The reporting tool needs only getName and getAddress. A team applies ISP and defines a small read-only interface with those two methods. Billing gets its own interface with the methods it needs. Each client now sees only what it uses.

Role interfaces have costs. They take more design effort, and they create a sense of dependence on the consumers, because the interface is shaped around them. Martin Fowler still prefers them and suggests pushing toward them as far as you can.

  • Interfaces are defined around the needs of specific consumers, not copied from all public methods of a class.
  • No component is forced to depend on methods it does not use.
  • No single large class or interface serves many different clients with many different methods.