Writing code that solves a whole class of problems is hard and that's what makes it fun. You get to flex your best engineering muscles, build a towering cathedral of abstraction, and feel rewarded when it all clicks into place and begins to work. β€οΈ
Yes the work took longer but think of all the time you'll save later!
- No more repetitive copypasta,
- fewer debates about the right way to do something (as long as everyone likes yours),
- no more explaining how things work (you wrote great documentation right?),
- and if something breaks there's 1 place to fix (ignoring the one-off exceptions you'll build over time)!
You explain to the waiting stakeholders that this was pre-work. An investment. It's going to pay back.
Except here's the thing:
Your abstraction is wrong, people don't understand how it works, and you'll soon find a bunch of exceptions that are near impossible to fit into your generalized approach. Yes we want this component to have the same behavior everywhere ... except on pages A and B where it needs a subtle change. Oh and C where everything is the same except in reverse. And we're not yet sure about D.
A few months pass and the next engineer says "This code looks messy ... lots of exceptions. Let me build a wrapper to make it easier".
Your codebase grows into a rickety pile of abstractions that nobody understands or dares to touch. Who knows what might break when every engineer for the past 5 years tried to build The One True Unifying Way Of Our System and never had the time to finish their grand vision.
Abstract code is hard to understand
Abstractions are fine. Encouraged even. You cannot write custom one-off code for everything. But there is a cost.
The big danger with abstract code is that you have to wade through layers of lettuce before you find code that does something. Keeping track as you bounce between files and functions is limited by your working memory and familiarity with the codebase.
Nothing worse than jumping through 5 abstract abstract wrapper wrappers before you find code that *does* something.
β Swizec Teller (@Swizec) July 26, 2023
As you build experience you can skim the code and look for common patterns instead of reading every line carefully. Similar to how chess experts think in higher level shapes instead of individual pieces, which gives them an almost magical ability to memorize complex plays. The more experienced you are as an engineer, the quicker you learn these patterns for a new codebase.
But unlike a chess board, you can't look at the entirety of your codebase. It's split among many contexts βΒ files and folders. Every time you jump between files feels like walking into the kitchen and going "Why did I come here?". That's the doorway effect βΒ you really do forget some of what you were doing when crossing a context boundary.
And because others work on the same code, you never know when something's gonna change. Your memory of how it works could be wrong!
The trick, then, is to keep related code close together to reduce context boundaries and to limit the amount of relevant detail so it fits in your working memory.
Avoid the hammer factory factory
Overly abstracted code goes by many names. None of them meant as a compliment.
My favorite shorthand is the hammer factory factory. An apocryphal developer wanted a hammer to hang up a picture, but nobody uses hammers anymore. What you want is a hammer factory so you can build any hammer you want. But that's lame too. Nowadays you want a hammer factory factory so you can build any factory that creates whatever tool you need.
Yes you have 1 picture and 1 nail and a 2 minute task. But think of the next time!
Cheers,
~Swizec
Continue reading about Say no to abstract code
Semantically similar articles hand-picked by GPT-4
- You can't fix the wrong abstraction
- Architecture is like a path in the woods
- You can't side-quest a product
- Why even care about code structure
- Solve the problem, not a different more difficult problem
Learned something new?
Read more Software Engineering Lessons from Production
I write articles with real insight into the career and skills of a modern software engineer. "Raw and honest from the heart!" as one reader described them. Fueled by lessons learned over 20 years of building production code for side-projects, small businesses, and hyper growth startups. Both successful and not.
Subscribe below π
Software Engineering Lessons from Production
Join Swizec's Newsletter and get insightful emails π on mindsets, tactics, and technical skills for your career. Real lessons from building production software. No bullshit.
"Man, love your simple writing! Yours is the only newsletter I open and only blog that I give a fuck to read & scroll till the end. And wow always take away lessons with me. Inspiring! And very relatable. π"
Have a burning question that you think I can answer? Hit me up on twitter and I'll do my best.
Who am I and who do I help? I'm Swizec Teller and I turn coders into engineers with "Raw and honest from the heart!" writing. No bullshit. Real insights into the career and skills of a modern software engineer.
Want to become a true senior engineer? Take ownership, have autonomy, and be a force multiplier on your team. The Senior Engineer Mindset ebook can help π swizec.com/senior-mindset. These are the shifts in mindset that unlocked my career.
Curious about Serverless and the modern backend? Check out Serverless Handbook, for frontend engineers π ServerlessHandbook.dev
Want to Stop copy pasting D3 examples and create data visualizations of your own? Learn how to build scalable dataviz React components your whole team can understand with React for Data Visualization
Want to get my best emails on JavaScript, React, Serverless, Fullstack Web, or Indie Hacking? Check out swizec.com/collections
Did someone amazing share this letter with you? Wonderful! You can sign up for my weekly letters for software engineers on their path to greatness, here: swizec.com/blog
Want to brush up on your modern JavaScript syntax? Check out my interactive cheatsheet: es6cheatsheet.com
By the way, just in case no one has told you it yet today: I love and appreciate you for who you are β€οΈ