The concept is simple, but its application is complicated. There is no metric for just how abstract a portion of code is, or how necessary or unnecessary the degree of abstraction a chunk of code is in the context of the problem it aims to solve. Perhaps the code needs to solve many problems, and a great degree of abstraction has merit, or perhaps the design is so bulky and complex the initial development time and long term maintenance overhead are staggering.
As one learns to program from theory and practice subjective analyses of programs and programming approaches develop. This comes from the realization that there can be many ways to solve the same problem, whereas in the beginning, the first solution is often the solution. Over time, one begins to consider many solutions to the same problem and weigh the tradeoffs of each approach prior to implementation.
There are many factors in such decisions; extensibility, maintainability, readability, portability, scalability, (wow software has a lot of abilities!), performance, line count, number of files etc, etc. A predominant factor in the private sector which is driven by revenue is the shorthand requirement: What is the quickest solution to develop that will solve the problem, without causing too many problems? Programming theory teaches us things like design patterns, tools to implement standardized solutions to problems that offer brief development time and strong marks in the aforementioned categories.
So why not just use design patterns to solve everything? Well, just as any programmer advances to realize there are many solutions to a single problem, one may grow to realize different patterns could be applicable to the same programming problem and again be faced with sorting out tradeoffs of one pattern vs another. In reality one size doesn’t fit all, and common patterns may need to be customized a bit or combined for a particular solution.
Imagine engineers who build cars, bridges, computers… Each of these engineers face the same issue software engineers do when designing a solution for a given problem. Even though a rocket engine could be strapped to a street car, it’s not something you see every day! The same essential idea applies to selecting the best approach in dealing with programming problems.
If you had to write a small program in PHP you knew would only be a few hundred lines if you wrote it from scratch would you use a framework? Another note on the requirements; this program will be used for about a month and then will be relegated to the attic where it will forever collect dust and never be used again.., still considering a framework? A framework could be a good choice for learning or experimental purposes, but in the interest of time and complexity it’s costly.
Abstraction also tends to introduce more action, like more function calls, and more complexity for the people working on the system. Calling a given technique inferior to another in a general regard is simply myopic. High degrees of abstraction lend themselves to large systems that need them. Consider this blanket statement in the context of building a street car: A rocket engine is generally considered superior to a V8. Even if you’re building a Ferrari a rocket engine is probably overkill even though you want the vehicle to go fast.
Abstraction is a dish best enjoyed over time, with an iterative approach to development. As more abstraction is called for on successive iterations of a product, add it. Of course folks like to think they can see down the road and introduce abstraction up front to offset the amount of future work, but think twice dear friend, or you may be making your life more complicated than it has to be (that goes for your team members too)! In an acronym Keep It Simple Stupid.
If you enjoyed this post please consider sharing it!