Any programmer can write an average piece of code, but it takes a little more effort and experience to produce good code. If we talk about a problem statement, there are various approaches you can take to solve it and not all of them are straightforward. A bad piece of code could solve the problem but a junior coder would struggle to understand how it solved the problem. It’s hard to define good code but learning what bad code looks like will give you a better understanding.
What is bad code?
Remember the time the deadline for a project was approaching and your project manager was constantly asking you when it’ll be done. You went on a coding spree, improvised wherever possible and somehow delivered the project on time with everything working just fine.
You knew your code was pretty bad, but it was your code and you thought you could always fix it at a later date. But you’re not the only coder. If this was a big project, you would have collaborated with several coders who wouldn’t understand that piece of code due to bad coding practice.
An example of bad code
Suppose that piece of code represents a microservice which constitutes a customer behavior module in a CRM offering. If they were to add a new feature to the module, suppose a new contact field, they would have no idea how to do it as they’re unable to understand and hence edit the code.
You can always add inline comments to add some clarity, but a good piece of code stands on its own. What would happen if you went on leave or left the company? Your code would be impossible to maintain.
What is good code?
With no clear distinction to what constitutes good code from bad, we may consider good code a combination of best practices and common philosophies. At the end of the day, you have to get these two right.
The three philosophies of good code
I came across this article that breaks down good code into a series of commandments. Commandments is a pretty strong word for an average developer to digest which is why I’d call them philosophies that a developer must follow in order to become a good coder:
Good code stands on its own
As I said, writing good code isn’t some miraculous feat but is a result of consistent effort and practice. If you were to compare the code you’re writing today to code you were writing a year ago, you would be able to tell you’ve come a long way as a coder. The code might be a lot more structured, readable and would allow another coder to take over. It is more likely to stand on its own. But does it? Can another coder working on the same project reuse it without giving a second thought?
Your code might contain dependencies and still be complete if those dependencies are obvious to get by. The real test comes when someone is working on your project. The philosophy is you should treat your code as you want others to treat you with theirs.
Suppose you’re adding a feature to allow users to geo-tag users in their photos. You’re supposed to write the base code and another developer is supposed to do the API integration with Google Places. If your code doesn’t stand on its own and is incomprehensible to the API developer, you may have to explain that to him which defeats the whole purpose of collaborative coding.
So, you came across this logical problem where you have to disallow user registration from a specific region on a client's website. It’s a simple problem statement. You have to geo-restrict a few locations, disable some form values, and display a message to inform the restricted users.
There are several ways to add geo-restrictions. You can let the users know as soon as they are on the website, select a restricted location in the registration form, or click the ‘registration’ button from a restricted location.
None of these approaches are wrong as long as they restrict the subset of users and the other developer maintaining your project can add or remove locations to the restricted list easily. Ideally, the change should be about changing a value under a ‘restrictedCountry’ array.
If the code isn’t obvious the developer might have to dig around the code to figure out the logic and loops, conclude if he has to make any code edits to absorb the changes, make the changes accordingly and then integrate the code.
Good code is structured, follows a set of common architectural principles, and contains independent code blocks. You’ve got to plan everything. You have to sit down with your solutions architect team, conduct R&D on the scope of the project, define the various project phases with deadlines, etc.
Code planning for a large project may take weeks even a month. The longer you plan the less likely you are to end up in a situation which may delay the project deadline.
How do I know if my code is good?
While these philosophies are good for setting up a developers’ mindset around what good code should constitute, the practices are more like instructions they can follow in their day-to-day programming assignments.
Comments should add value
Comments can only add value to good code as they provide more clarity. If your code is too reliant on comments then it’s bad code, then you must consider rewriting it before adding any more comments.
You spent weeks making sure the code will be well structured, but is it at the end of the project? Indentation takes collaborative efforts of various stakeholders. It should be obvious for all the developers on the project to understand where a block of code starts and where it ends. Indentation is all about making the codebase well-defined and straightforward to understand.
Classes should stick to the single responsibility principle (SRP). Good naming conventions, together with SRP, make a developers’ life much simpler when trying to understand a new project.
Naming conventions should differ with various scopes if a Class is executing an intensive scope of work. When and where a variable goes out of scope with a single glance at the code block is a good place to start.
Use expressive naming conventions for all but the most transient objects. An informative name says a lot about when and how to use the object.
Avoid magic numbers, constants, and hard strings
One constant in your entire codebase is bad, two are ugly, and three are a recipe for disaster. Once the code is a part of the main branch, figuring out the constant’s value would take going through the entire codebase and no developer has this amount of spare time. What if changing this magical number crashes the entire program? Hard strings are a bad code choice if you’re looking to localize your application.
I came across this image on BetterProgramming, which they believe is self-explanatory.
How do you write good code?
According to the most upvoted answer on Stack Overflow to “What does a good programmer's code look like? ” good code is organized, tested, straightforward and independent.