Card 06/ 08
One Interface per Method
Splitting every method into its own interface trades one problem for a hundred names.
Splitting interfaces until each holds one method is a misreading of the interface segregation principle. The principle shapes interfaces by their clients, and most clients call several methods together. This card explains why a single method per interface usually goes too far, and how to tell.
The expectation is natural after the Worker refactoring: if smaller is better, the smallest must be best. So a team splits UserRepository into UserFinder, UserSaver, UserDeleter, UserCounter and UserExistsChecker. Every client now needs three or four of them, so every constructor takes three or four parameters, and every implementation implements five interfaces that always appear together.
The test is whether a client ever uses one piece without the others. If every caller that finds a user also saves one, find and save belong in one interface, because no client is forced to depend on a method it does not use. Splitting them adds names, imports and wiring without removing any dependency.
Split by clientEach interface matches what some caller uses
UserReader with find and count for reports. UserWriter with save and delete for the admin screen. Each client takes one parameter.
Split by methodEach interface holds one method
Five interfaces, always used in the same groups. Every client takes several of them, and adding a method means adding another name.
collections.abc uses single-method interfaces because there, real clients do use them alone: len really only needs Sized. That is the evidence a split needs. Without a client that uses a piece on its own, keep the methods together.
← → move through sections and cards