We humans have a marked tendency to take things too far.
It’s not just celebrities and the wanton parasite class of billionaires and centimillionaires. After all, who really needs (or wants) a 126-meter, 8-deck luxury yacht that requires 63 crew to service a mere 26 guests (but only if they’re willing to double up)? Or an $85 million Bel Air mansion with 10 bedrooms, 15 bathrooms, and a ballroom that seats 200-250 people? Oh, and eight rose gardens.
Eight.
In a world where thousands of children die needlessly each day, such excess is despicable. But most humans wet their pants with excitement just thinking of it. Go figure.
That said, we are all guilty of it to some degree. Who among us has only what we really need? And the desire to commute by Ferrari when a VW (or a bus or a bike) will do is as common as seawater.
I see this also in industry, and particularly in tech work.
I’ve made this mistake myself, when I was young(er) and somewhat naïve. I remember a decade ago or so having a smart young friend over for drinks, and I could hardly wait to show him the absurdly over-engineered app I’d built.
Imagine my chagrin when he said, “Oh, Charles! Never write a line of code until you have to!”
I was blown away by that comment. It changed everything for me. I’d been teaching “just-in-time” for more than a decade, but, oddly, I’d been coding “just-in-case”. Doh!
Abstraction is not your friend
Abstraction can be useful because it amplifies power. But the price is often complexity and mystification. In programming, we tend to abstract too early and too often.
But as my friend, Guillermo, said to me (in effect): never abstract until you have to.
That means that if you have only one instance of a particular widget or algorithm, then make it fit for that specific purpose and no other.
If you have two very similar widgets, hmm. Probably still not worth abstracting the pattern out. Got three, four, more? OK, maybe now.
Developers have become so afraid of “repeating themselves” that often they will abstract everything.
I had the great displeasure of working on a code base recently where things had been abstracted to absurd lengths. At least one of the devs was highly enamored of composition, apparently, so nothing was simple or straightforward. It was all functions wrapped in functions wrapped in functions wrapped in functions — and all, ostensibly, to make things easier.
Ha, ha. You can’t make this shit up.
It took me the better part of an hour to figure out how a very simple feature worked because what should have been a few lines of code in one file had grown like a pernicious weed into a hundred lines or more spread over eight files. It was like being in a horror movie.
And this pattern was repeated all throughout that app. A very simple and discrete application had been bloated into a monstrosity to make it more “configurable” and “reusable” when it would never be reused and could have avoided configuration entirely by simply being fit for purpose and no more.
KISS
Just keep it simple, stupid.
The Principle of Least Power says don’t use a flamethrower when a Bunsen burner will do. Worse is better. Less is more.
Don’t become so obsessed with DRY [don’t repeat yourself] that you abstract the hell out of everything. Don’t add dependencies until you absolutely need them, and then add the simplest and fewest you can. Don’t add features until someone requests them.
Over-engineering and overbuilding waste time, money, and effort, just as feature bloat does. Build things just in time and just enough. Do we really need a chainsaw? Or will this paring knife be enough?
This issue is particularly rampant in “enterprise”. Nothing gets a manager more excited than complex systems. They all like to pretend that they’re Google.
Google processes nearly 100,000 search queries every second. I’ve worked for companies that were lucky to get that many hits in a month, but they wanted to emulate Google’s processes. It’s insanity.
I’ve decided to embrace exitprise instead. As in, I’m outta here.
Keep your code as simple as you can. Keep dependencies to a minimum. Split your apps up into decoupled components with intelligent boundaries. Avoid rushing to use the latest cool toy — you don’t have to be cool to rule my world. Write the code yourself whenever possible.
You’ll keep tech debt to a minimum. You won’t be held hostage by your dependencies. Your surface area for attacks will be much smaller. And you’ll know your own code base inside out.
Try it and see for yourself.