The Interface Segration Principle is one of the more overlooked parts of SOLID. I think this might be because it gets seen as a restatement of the Single Responsibility Principle, and not as the separate idea that it actually is.
Interface segration is about keeping interfaces lean and specific to the smallest possible purpose, as suggested by the formal definition:
“No client should be forced to depend on methods it does not use.”
I covered this a bit in Easier interface segregation in TypeScript.
One way to achieve better interface segration is to focus on what a client actually needs, rather than on pre-planning what you think an interface should be.
In other words, implement the client code first, and then extract the required interface from there. It might turn out that there should really be several smaller interfaces than one implementation that covers all of them. This is a good finding, as it will result in smaller, segrated interfaces that are easier to refactor later if necessary.
As a rule, the smaller the interface, the easier it is to refactor.
It’s more common to consider that one interface might have multiple implementations, but rarer to remember that one implementation class might implement multiple interfaces. Again, bearing this in mind can lead to smaller, cleaner interfaces that serve one purpose. These will be easier to manage as the application changes over time.