False Abstractions

A common mistake in software engineering is to jump too quickly into building an abstraction while requirements and specifications are still not well understood. This leads to false abstractions, which are costly to maintain when things inevitably change; all dependencies have the added overhead of wrangling with a poor design. A basic example is creating an interface when only a single implementation has been worked out. At some point, another one comes along and doesn't align. The author can attempt to refactor the interface to fit both implementations, though at this point its existence is dubious, and who knows how many times this exercise will need to be repeated for future implementations. Alternatively, the interface can be scrapped entirely. Either way, all dependencies will need changes. In this case, the best decision would have been to avoid creating the interface at all.

It's better to be explicit and keep things separated until a true abstraction can be made; the tradeoff is more work upfront, but less work down the line. It's important to contain and resolve a false abstraction when spotted to minimize tech debt. For example, tying a database schema to one of these can be very costly. Having the discipline to refrain from being overeager about abstractions can be difficult, since building abstractions satisfies our creative appetites as programmers. It's a case where the good intention of trying to keep things simple actually makes things more complicated.