When abstraction, design patterns, and principles leads to spaghetti code
Published on 2019-05-26.
If you are thinking about abstraction, design patterns, and programming principles while you are programming, then you are not really programming. Rather you are wasting time fantasizing, not solving problems. The end goal is always to have good working code, not code that has been bent, twisted, and shoved into formations and structures in order to fulfill the vanity of someone living in a fairy tail.
Some time ago I was going through a code block of some very efficient Go code for a web application. The block was a single function that consisted of several function calls to other functions, some logging, some error handling, and some clean up that made sure that incoming requests was finalized properly.
Some time thereafter someone decided that the code block needed refactoring, not because it was hard to read, and not because it wasn't performing well. No, because it didn't follow any of the famous guiding principles of proper code development.
I know that the person who decided to refactor the code did so with the best of intentions. After all he had clearly followed every single principle and design pattern to the letter. The problem however was, as so often is the case, that by following the famous principles fanatically the end result was a horrible mess. Before he had touched the code, the code was performing extremely well, it was easy to read, understand, and to keep track of each step in the code.
The first thing he had done was to implement the single responsibility principle by cutting each part of the code up into tiny functions in separate files.
In order to do that and still make the code work he had to implement new functions that called previous functions that again called some new recursive functions.
The next step he did was to implement interfaces because according to his perceptions, responsibility has to be abstracted away. The end result was code that:
- No longer performed as well.
- Consisted of at least twice as much code.
- Could no longer be easily tracked.
- At least thrice as much time reading the code, once you had tracked everything down and actually figured out what belonged to what.
Even if the end result would have been code that performed just as well as the original code, the refactor was a bad call because there is something called overengineering!
Code is a tool you use to solve problems. It's not something that has to fit into principles in order to solve problems.
If you were to implement every single safety principle that exists regarding transportation in a personal motor vehicle, it would become so heavy and require so much extra equipment, that it would literally become impossible for one person to operate. Not to speak of cost inefficient.
Programming principles are just guidelines and theory. Some are even good standard rules of thumb. But they are NOT something that should dictate how you solve your problems!
Consider these points:
- Focus on the problem as the main concern.
- Never implement a principle just for the sake of the principle! Use principles cautiously and as guidelines only.
- Understand and differentiate between really pragmatic principles and less useful things such as Design Patterns.
- There are no fixed set of rules that dictates how you need to solve a programming problem.
- Good code is never about the code, it's always about the problem.
- Efficient code is very often quite contrary to code developed with a focus on principles.
The end result has often very little to do with code. Your code is completely worthless if it doesn't solve the problem efficiently and economically, and with economically I mean both financially and environmentally. Efficient code requires much less hardware and power - and this is important. The general idea that hardware is cheap and you can just throw more hardware at inefficient code is not only irresponsible, but it is also childish.
As developers we need to keep our focus on the really important stuff, not on the academic theory and "fanatical babbling" of people who like to feel important.