Edit: Now also available on my blog.
I choose a lazy person to do a hard job. Because a lazy person will find an easy way to do it. - Bill Gates
This article is intended to teach you how to do your daily job as a software engineer -and do it very well- with the minimal amount of efforts.
While I do believe this will have some interesting information for most readers, it will be an especially great read for people who struggle with ADHD. If you know a programmer or aspiring programmer in this situation, you might help them (and myself) by sharing this article.
Let's start.
I - Using Your Brain Considered Harmful
I dislike using my brain.
The reason is, using your brain is hard. Most people will avoid doing hard things too often. If you can do a great job without efforts, then why should you? You don't get extra points for difficulty.
Job satisfaction increases when you're not suffering. Your energy levels stays high, your productivity as well.
There is a secret to achieving high efficiency with minimal efforts, it's called "being smart about it". Martial artists achieve high efficiency by applying high pressure onto an opponent's sensitive points. That's knowledge well used.
Let's be smart about it then.
II - Problem: Software engineering is complicated.
Well, then we just have to make it simple, this way we won't have to think too much.
Turns out, this task is also the best description of the work of a software engineer: reducing complexity.
Complexity is bad. Very, very bad. It is your job to make everything as simple as possible. As we will discuss later, this is the part where you actually need to be smart and use your brain.
We achieve simplicity via both programming practices, and work methodologies. Some examples:
Programming practices
Elegant, high-quality code. Following best practices. Using the right OOP patterns at the right time, functional programming when it makes sense. Refactoring. Avoiding technical debt and spaghetti code. You get the idea, but this is not what this article is about, we're here for the next section:
Work methodologies
Let's explore some work methods that will help you save on all that precious brainpower.
III - When to think hard, and how to do it.
As you will notice, the methodologies I will detail are not really about not thinking. They are about thinking hard, at the right time.
I do believe there are merits in the saying: "Sleep only when you're very sleepy, eat only when you're very hungry". I would add: "Think hard only when you really need to think hard".
Knowing when to think hard and then actually thinking hard is key to building great software.
Here are two great work methods to achieve great thinking:
Deep work: as explained by Cal Newport in his (amazing) book, it's all about maximizing work efficiency by achieving high focus.
Pomodoros: By cutting your work into small time fractions and combining this with deep work, you can actually achieve your best work.
Feel free to research those topics, because I will not detail them here. We're going to focus less on how to use your brain and more on when to use your brain.
IV - Work methodologies for the dumb and the lazy.
Atomic Git commits
The way you use Git can force you to use your brain more efficiently. I strongly advise you to read the linked article, it explains why quite well.
The gist is: using Atomic Git commits forces you to map in your head the exact suite of commits necessary to achieve your goals, in small steps.
Breaking up a big task into smaller, simpler, easier steps? That's the textbook recipe for reducing complexity!
The difficulty with this method is that you have to pay in mental currency at the very beginning. As they say, "A week of coding can save on 30 minutes of planning". Still, because thinking is hard, we tend not to do it. That is a mistake, because you will have to pay the interests later.
Once you've cut your task into smaller steps, you can turn off your brain. You won't need that bag of meat anymore.
BDD, Not TDD.
So I'm definitely not making friends here (hello ThePrimeagen, hope you like this one as well), since this is a very controversial topic. This will digress somewhat, but I think in an interesting way. Disclaimer, this is only my opinion, yadda-yadda.
I strongly believe that Behavior-Driven Development is an amazing tool to use your brain as little as possible while achieving high-quality code.
I use the term "Behavior-Driven Development" to address a common criticism of Test-Driven Development, which is "You don't know what you want at first, so when doing TDD you have to rewrite your tests once you know what you want".
I believe there is a misunderstanding here between opponents and proponents of TDD, and the misunderstanding might stem from confusion between TDD and BDD.
What supporters of TDD/BDD are hearing is: "I don't know the specifications I'm supposed to fulfill". This sounds ridiculous: If you don't know what you're supposed to achieve, you should definitely go have a brain-using session until you clarified your specifications.
What the opponents of TDD are actually saying is: "I don't know the steps that will lead me to fulfill my specifications".
The difference between those is basically unit testing. Of course you very rarely know what the details of your code will look like before you write it, so if you're unit testing small portions of code -such as your methods- you will end up rewriting a lot of (mostly useless) tests and have a miserable time.
The right smallest unit to test in an OOP context is in my opinion generally the Class. And if you thought long enough about the architecture of your code (for example when you were breaking down your task in smaller steps, see Atomic Git Commits), you will know which classes you want at every step of the way.
Hence, you will never have to rewrite anything.
As I said before, I do believe that you should think long and hard before doing any coding, at least until you know exactly what your specifications are, including some hard thinking about possible edge cases.
This is what BDD is all about: thinking hard about your exact specifications and coding them first. You know what you want, and once it's in the code, you just need to make the specs go brrrr green.
Frankly, once your specs are written down, you can turn off your brain. The rest of the work can barely be called "work".
Conclusion
I hope you found something interesting in this article. Don't hesitate to share if you think this can help someone struggle less with the daily demands of software engineering.
As for discussing pro or against TDD/BDD, the comment section is down there π.
Top comments (18)
"A week of coding can save on 30 minutes of planning" :D
My buddy once said "Writing great code is easy, it's the coming up with it part that's hard".
But seriously, I agree with the need to reducing complexity, I always go back to telling folks that old adage about the human brain only having RAM for like 5 things.
To this end, I think TDD is helpful, even if you have to write a couple of tests that will ultimately be rewritten - it's a way to leave a breadcrumb to return to later without sweating about it too much. It's an unfortunate fact often missed in TDD talk that to write proper specifications, you need to have some code for things to start falling into place. It's an iterative process - stumble about a bit, drop some breadcrumbs, hit on the core behavior and the structure you want for it, specify that, get something working, return to breadcrumbs.
It's a sort of journey from the very detailed out to the most overarching and back again, but now with a clue about what needs to be built, and how.
As usual, comments are welcome.
This was an interesting one! Great writing and a good read.
I liked this bit in particular:
Haha, well said. That's gonna stick with me.
Really nice one....
The level of problem you are solving contributes to code complexity. The way you are solving it is is contributed by your level of expertise and your target users, their platform, their adoption, their preferred requirements.
Using your brain is the best part of being an engineer.
Great writeup. I am going start practicing this in dev for today.
My favourite line comes from your post on Atomic Git Commits
Thank you
I like the links, but that really triggered my ADHD haha. I do feel like the Grug at times from the very, very, bad link thus google searching and found your article. And I totally understand the TDD dilema, AND TDD is awesome, and this is the first time I have seen BDD, which could also be great intertwining the two.
I cannot agree with you enough βΊοΈ. Thanks a lot for illustrating it.
A reassuring sentence I repeat to my customers is,
"If we can define it, I can create it".
Thus, the burden of hard thinking is shared with the customer, and the expecations won't go wild.
Moreover, I really need to make small commits. Very small. As most of my coding experience is through a textual ssh screen, a unit of commit will usually span just a few file changes, done one by one π, of course.
And, in the really dangerous field of service management, I constantly oppose changing more than one thing at a time. This, to be hands on when something breaks, and reduce the debt.
As a "seasoned" software engineer, my clients expect me for solving their problems by thinking the issues through, not just through coding. Some problems are too complicated for one person to solve through coding alone and need a coordinated response.
Adopting a solution with insufficient thought is only creating problems for later (aka Technical Debt). Whilst this might sound a good strategy for career protection, the reality is your clients will not be impressed.
I suspect it will be those jobs that do not require human brain power that will be most at risk of being replaced by AI.
I envy you your clients value your planning. I had to take this by force.
I agree and this is why thinking long and hard at the right time is important.
One can argue that quick code prototyping is actually a way to build understanding about the task and if necessary to rewrite, that's fine.
Expecially in old projects, they already use existing frameworks for achieving specific objectives. So often I find it necessary to do some exploratory coding before figuring out how exactly something needs to be implemented in a consistent for the project approach. This is especially true with "opinionated" frameworks, where going on your own way is a path covered with tears...
So it depends.
Actually I find it hard when I have to figure out how to change something that 100 other things depend on. More often than not, new features are on the fun side.
The Prime mentioned π₯
Let's goooooo π₯π
It 's on what one should stay focus and concentrate. Not to drain our mental energy.
Interesting.