To design an effective interface, you must balance several criteria. In general, you should try to develop interfaces that are:
Unified. A single interface should define a consistent abstraction with a clear unifying theme. If a function does not fit within that theme, it should be defined in a separate interface.
Simple. To the extent that the underlying implementation is itself complex, the interface must hide as much of that complexity from the client as possible.
Sufficient. When clients use an abstraction, the interface must provide sufficient functionality to meet their needs. If some critical operation is missing from an interface, clients may decide to abandon it and develop their own, more powerful abstraction. As important as simplicity is, the designer must avoid simplifying an interface to the point that it becomes useless.
General. A well-designed interface should be flexible enough to meet the needs of many different clients. An interface that performs a narrowly defined set of operations for one client is not as useful as one that can be used in many different situations.
Stable. The functions defined in an interface should continue to have precisely the same structure and effect, even if their underlying implementation changes. Making changes in the behavior of an interface forces clients to change their programs, which compromises the value of the interface.
Quoted from Programming Abstractions in C++, (Chapter 2.7).