In my early career as a software engineer, completing features as many as possible and as fast as possible was my main goal. I felt proud if I can finish my project early or produce many features without considering if the user will use them or not.
Then suddenly user asked for changes, and the codes were hard to change because of tech debt. Software became more unusable, couldn't meet the deadline, the user was angry, and slowly pride became stressed. Years later I've found these 6 habits will help me to build better software.
Understanding the Goal
When building the software we always got technical specifications or requirements. It explains how a feature should work, but we also often got requirements that are too abstract to understand. We, as an engineer has a job to break down those abstract requirements into executable coding work.
Not knowing the main reason why the feature needs to be built often leads me to build something that has no value. So I begin to always ask why users need a feature or requirement change. Some points which I often to digging out:
Why user needs the feature?
How important are the changes or the feature to help users?
Are there any dependencies with other features?
Is it a temporary or long-term solution?
Those two first questions usually helped me to know if a feature or change is needed or not.
Wait, how can be there a feature that turns out to be unnecessary?
It could be that the person being asked has a fairly simple goal but the product owner or client making it too complicated. Asking for complex automation when what is needed can be solved with Excel / Spreadsheet. Of course, it must be discussed so that a middle way can be found. This helps us to avoid work that ends in vain.
Always Start with Planning
Early in my career, I rarely code with a plan. Just code and ship as fast as possible then figure out a solution later. Sometimes I've put some "cool" abstraction without thinking deeper about trade-offs just for the sake of "cool-looking" code. Then I ended up with many unnecessary codes or let's say over-engineering. It was hard later to understand for other engineers even me because for simple flow we have to track many unnecessary files.
Planning doesn't need to be very detailed. It also depends on the requirement complexities.
Planning code for CRUD an article and the planning code for a payment integration it's different.
Simple CRUD might not need 3rd party dependencies, but payment integration is. So my rule of thumb for planning are:
Acknowledge internal & internal dependencies or modules
Checking if our specification is clear enough or not
Checking if I need to be aware of performance and security
Depending on the time factor (deadline), I need to be aware of cutting edge and need to understand the trade-offs
Checking whether my changes have a risk of breaking changes in current features or other dependent services
Even with a plan, sometimes we have roadblocks that made our plan obsolete. The point is, planning can reduce the risk of roadblocks because we already anticipate that.
Do Self Code Review
Code review is an activity to make sure our code changes are following standards or to check if any flaws need to be addressed especially if multiple engineers are working on the same codebase. Even when I code as a single programmer, I always create a PR and then do a code review for my codes. When working with a team, I review my code first and adjust some changes if needed before I ask my team to do a code review.
is it just wasting my time?
Reviewing my code changes in a Pull Request often gives me a new perspective that I couldn't see while I'm coding. Such as typos, wrong conditions, optimization ideas, etc. It also gives me more confidence before I merge it to the main branch or asking a code review to my teammates.
I will refactor this code later
And after months, no time to refactor. Lol.
Remember the self-code review? There's a chance we see some part that can be cleaned up or made in a better way. I'm not talking about huge refactoring which can cause unnecessary breaking or take more effort, but make sure to clean up the codes and make it understandable before merging it to the main branch.
Write and Do Testing
Sometimes we're too lazy to test our work, especially if we have a QA person who can test it later. This is bad for our accountability as software engineer because quality is all team responsibility, especially the person who wrote it.
Make sure our code is working as expected behavior
Make sure our changes are not breaking another service if we or they have dependencies with our work
Make sure some common negative case is already handled. In some cases, we also can test for critical edge cases
If possible, create unit tests or functional tests for each feature we built. This is the hard part because it needs discipline and experience in how to write tests. It requires effort but surely will help a lot later during the next development phase. It's almost like a guarantee for our code stability.
Also if we want to write unit test, we just can't write code without thinking about how our code could be testable. This kind of mindset will help us how to write better architecture and testable codes.
So start investing time to learn unit tests or even Test Driven Development to get more insight.
Technical Documentation is really helpful especially if we're working with teams and can reduce ambiguity about how the system works. The most simple documentation is writing detail for each given task to our task management. It will give better context for other teammates about what we're working on right now.
Other documents are:
RFC (Request For Comment) or Blueprint: It's common for kind of complex tech initiatives that requires many concerns so each engineer can add comment or feedback. Later we can use this document as a guide for the development.
Wiki: It's a document that usually explains how to operate something. For example, a wiki that contains how to debug a login activity and how to resend an OTP password.
I believe good documentation is very valuable to a team because it will reduce many unnecessary meetings because they are missing some context. Will help you to understand the system better and level up your technical writing skill.
If you're confused about your document, maybe another person doesn't even understand.
These good habits cannot be done instantly. It needs discipline and gradual evaluation of whether it is indeed useful or not in providing good results in the process of making the software itself.
So what's your good habit?