Levels of abstraction
It's necessary to find the right one
Creating software involves creating abstractions. Abstractions which serve as building blocks to construct bigger pieces, which in turn allow building bigger blocks, etc. Finally, from the biggest blocks, the whole solution can be constructed.
For each abstraction, it’s important to choose the right level. The building block should be general enough to allow its reuse in many places. It also cannot be too abstract, so that its usage will not be too cumbersome.
When something is built too abstractly it shifts the burden of the proper usage of the call site. Too many details are required in order to use such abstraction, which makes it less than ideal to use. It will also cause the abstraction to leak, the usage requiring to know too much of the internal structure. This, in turn, makes it much harder to modify implementation details.
Something which is too concrete will not be reusable across the project. The rigidity of the solution will not permit to adjust it to the exact place where it is needed.
The appropriate level of abstraction is context dependent. What is too abstract solution for one component in one project can be too concrete for another. It could be also that a given component is abstract enough for that layer of software but would be inappropriate when moved up or down.
Finding the right level of abstraction moves the software creation to another level where solutions can be made easier. Creating right building blocks help to deconstruct the problem into manageable pieces, pieces which can be assembled together to provide the end result.