How to think like a software developer
A productivity mindset you can apply to almost anything
Changing the game is a mindset.
— Robert Rodriguez
As a software developer, I constantly ask myself: what distinguishes an outstanding developer from a mediocre one? From my observation, it has very little to do with formal education, age, gender, and even industry experience. It has a lot to do with mindset.
Developing software is very much like cooking. All legendary chefs must first grasp the common fundamentals of food preparation and kitchen processes. Only with these fundamentals then can their unique personality traits shine through. Great developers are as creatively diverse as they come, yet they share an eerily common mindset, upon which they build their craft.
By no stretch of the imagination do I count me amongst the ranks of great software developers. I do, however, make it a point to continuously study the effective mindsets of outstanding software developers in order to emulate them.
Why should you care about how a software developer thinks? Aren’t they a bunch of nerds tip-tapping on keyboards? Well yes, but the software developer’s mindset can be applied to many areas of your life, for example, in your business, your side hustle, investments, hobbies, sports or learning a new skill.
Let us dissect the cornerstone concepts of how a software developer thinks. Using your abstract thinking, you can use them as mental blueprints to engage your daily undertakings.
Learn how to learn
If I have to pick one single skill that is absolutely essential to a software developer, it would be the ability to self-teach.
Developers teach themselves by reading books, consuming blogs, working through tutorials, attending training and doing mini projects.
When faced with programming problems, developers comb forums such as Stack Overflow for hints and solutions. More often than not, the solution has probably been figured out by someone else.
Yes, it is possible to survive as a software developer without learning anything new. The high price to pay for doing so is to be pigeon-holed into fixed product or technology role.
Learning something new is a delicate dance between consuming information and trying stuff out for yourself. If you rely on consuming information, you will not be able to independently produce solutions. If you only learn via trial and error, you will miss out on leveraging readily available information. For example, reading about writing does make you a better writer, but only if you put in the time writing.
Develop a passion for learning. If you do, you will never cease to grow.
— Anthony J. D’Angelo
With a few exceptions like the legal or medical field, the ability to teach ourselves new skills triumphs formal education. Just like a software developer, we should ceaselessly teach ourselves new skills to maintain our competitive relevance.
The challenge is to balance both avenues of self-education: active information consumption and learning via trial and error.
Don’t reinvent the wheel
When developing software, you almost never have to start from scratch. You have your pick from a myriad of programming languages, frameworks, infrastructure and tools.
The Not Invented Here (NIH) syndrome in the software industry describes the tendency to reinvent the wheel, despite the availability of existing tools and software from other vendors. It is very easy to fall into this trap because creating software is comparatively cheaper than creating components in other industries.
There are good reasons for reinventing your own wheel. One very valid reason is if the existing solutions out there do not meet your requirements. Even if that was the case, some open source solutions allow you to extend or modify them.
On the other hand, there are terrible reasons to reinvent the wheel, including but not limited to:
- deluded by the ego to presume that a homegrown solution is always better
- too lazy to figure out what solutions are out there
Reusing existing software has the obvious benefits of saving time and effort. In the long run, you will benefit from the bug fixes and new features that the developer of the software provides.
When undertaking a venture, it is prudent to look around if we can appropriate existing solutions. We can ask ourselves questions like:
- what relevant ideas are already out there?
- has someone else figured out a system or a process?
- are there any existing solutions that we can build on?
- are there available tools?
- are there any available services we can use?
The software development process is an iterative process. The iterative thinking can be seen on multiple levels, from daily programming tasks to product releases that span weeks or months.
The basic idea of an iteration is to plan, execute, test and learn.
The shorter the iterations are, the faster the feedback can be incorporated back into the next development cycle. Prior to the 1990s, it was typical to have longer product development cycles that span up to 6 months before a solution reaches the customer. The current approach is to have much shorter iterations. Some software companies even deploy solutions to productive systems multiple times a day.
Having an iterative approach gives us permission to be less harsh on ourselves when we are faced with those “could have, should have, would have - done things better” moments. This is because if we missed out on doing something well in this iteration, we can fix it in the next iteration.
It is soothing to know that we do not have to be perfect, we just have to continuously improve.
The other major benefit of working in iterations is that we are lightened from the mental burden of figuring everything out from the start. Without ignoring the bigger picture, we only need enough plans and decisions for the current iteration. The decisions of future iterations can be left out for the time being, as they will also depend on the learnings of the current iteration.
The iterative mindset can be applied to almost any project-based undertaking. The approach is systematic, effective, practical and easy to implement.
Test, test, test
An integral part of a software developer’s job is testing. Despite the code is usually written to the best of one’s intentions, there will still be errors. The errors caused by either unintentional mistakes or erroneous assumptions.
A good software developer is never under the illusion that a piece of software is free of bugs. The whole software industry accepts that errors are just part and parcel of the process. That is the reason why so many tools, frameworks, and methodologies created to detect errors.
The goal of testing is to catch those pesky bugs as soon as possible. The earlier bugs are detected, the cheaper they are to fix. An error that takes 5 minutes to fix on the developer's machine can cost millions in legal damages if left to reach the customers’ side.
In any enterprise we undertake, we will inescapably make mistakes. Just like with software, the earlier we detect them the better. It is wise to test our assumptions before committing further resources to a certain cause.
One effective way to test is to try something out on a smaller scale. For example, if we assume that we can learn a living as a full-time photographer, it would be a good idea to try it out as a side hustle before quitting our full-time job.
It is also very possible that we have wrong assumptions about ourselves. Typical mistakes are assumptions about our interests. With modern media, it is easy to have a romanticized view of success without seeing the effort invested by those who have achieved them. Such skewed views might cause us to assume false interests in certain fields. The only way to figure out if we might like something is to test the waters before going all-in.
Until we check them, assumptions are nothing but unproven thoughts swirling in our heads. Testing is a good way to distill assumptions into verified truths. The key to testing is to commit as little resources as possible before finding errors as early as possible.
Apply learned patterns
Design patterns in software engineering are generalized, reusable solutions to a recurring problem. It is not a piece of code, but rather an idea template that can be applied when you write your own code.
Let us take the Facade pattern as a concrete example of a design pattern.
A software system can consist of a complex mess of multiple subsystems. If we are not careful in the design, there will be a messy communication between the components of the subsystems. The Facade pattern tells us to use a “facade” to hide the complexity of a subsystem. Other subsystems just talk to this facade instead of the individual components of that particular subsystem.
The Facade pattern is not a new pattern. It was first described in the book titled “Design Patterns: Elements of Reusable Object-Oriented Software”, published in 1994. Yet, it is still very relevant today.
Great software developers study design patterns in software. They understand that design patterns can provide a structured approach to solving the problems they have. More importantly, they know when to apply which pattern.
Studying the generous contributions of that come before us will save us the pain of discovering the same ideas by mistakes. Applying patterns to solve problems is like solving a Rubik’s cube. When you know the steps you have to take, the problem suddenly becomes easy to solve.
There are obvious ways to learn patterns such as how-to guides or classroom training sessions. Yet, patterns can be seen everywhere, sometimes hiding in plain sight. One of my favorite ways to learn patterns is to read biographies of people who are successful in their respective fields.
Patterns are never cookie-cutter solutions that can be universally applied. They are like tools in the shed. Experience and discernment will tell us that not every task can be solved with a hammer.
Don’t fall in love with your work
Great software developers practice a very important distinction: they love what they do but they are do not fall in love with the work they produce.
To be decent at anything, including software development, there is a certain threshold of passion necessary. We need the fire of enthusiasm to propel us over the challenging humps of the mundane plateaus.
Despite having passion, great developers are not attached to the work they produce. This zen-like detachment offers multiple blessings, especially when our job requires us to be innovative:
- more open to constructive feedback from others
- more objective when evaluating alternative solutions
- higher chance of trying a drastically different approach in the next version or iteration
- more willing to try out drastic ideas, despite knowing that there is a high risk of them being discarded
From personal experience, I have to admit that distancing myself emotionally from the work I produce is not easy. It does hurt when I discard prototypes after working days or weeks on them.
Attachment to our work can be explained by the Sunk Cost Fallacy. It implies that the more we invest in something, the harder it is to abandon it.
The notion of being detached to what we have built can be helpful in all areas of life. Detachment prevents us from holding on to something for too long, especially when it no longer serves our current cause.
Perhaps we are clinging on to that half-dead low-profit side hustle that has been draining our time. Or maybe it is time reevaluate our whole investment portfolio.
Attachment to our work is akin to standing in a forest, holding tight to a wooden puppet that we have once carved out in the past. There are endless opportunities to create more beautiful puppets. The first step to making new ones is to put the old one down.
Give developer thinking a try
If you are a software developer, try applying what you are already doing professionally to other aspects of your life. You might be surprised at the wealth of productivity tools you already possess.
If you are not a software developer, give the power of thinking like a nerd a chance! Break down those concepts and repurpose them to achieve your goals.