Software developers love abstractions. It is satisfying to hide the perceived ugliness and complexity of the underlying system in a so-called easy to use, beautiful interface. Also, abstractions are considered a good design practice.
The abstractions that I am referring to are those along the lines of structural design patterns like adapter and facade. ORM is a classic example.
The flip side of abstractions is the complexity that it brings. Abstractions would have bitten every software developer at one point or the other. Cursing ORMs is a rite of passage for web developers.
Poorly written abstractions cause more problems than they solve. Not to mention the countless hours wasted in designing, writing, and maintaining them.
Knowing when not to abstract is as vital as knowing when to abstract.
When not to abstract?
- The abstraction does not add value.
- The underlying thing that you are abstracting is not a standard and is rapidly evolving.
- You are prototyping.
- You are short on time.
Before writing an abstraction, always introspect—what is it I am solving with this abstraction? What is the value add of this abstraction?
Abstractions work well when they are written over components adhering to well defined, comprehensive standards and specifications. For example, SQL is a well-defined standard. SQL might evolve, but slowly. Hence ORMs are ubiquitous and work well for a majority of the use cases.
When you try to abstract a non-standard rapidly growing platform, it becomes a game of catch up and drastic design changes each time the underlying platform changes. Without knowing the direction of evolution of the underlying platform, it becomes a disruptive change each time to the users of your abstraction.
When you are prototyping, concentrate on proving the idea as quickly as possible. Do not waste time writing layers of abstraction, which you might throw away in the future if the concept does not work.
Abstractions that add value require deep focus and ample time to design. If you are short on time, you will do a lousy job with the abstraction. It will cause problems than solving something.
In all the above cases, instead of structural abstractions, concentrate on utility functions. Writing utility functions for simplifying recurring patterns will give you more bang for the buck.