This article is a supplementary piece to this Group Discussion about Code Quality & Review at GeekyAnts.
Watch the video here:
For the rest: read on:
Of course the technology and language that you use to build a product is important, but you can’t read a book if it uses words with incorrect context, misplaced sentences and stupid amount of spaces between words.
Code quality is just an equally important part of product development as building it & managing it is. Good code quality is what really makes your product stand out, perform better and easier to enhance.
In recent times, code quality has been given the attention it deserves but still remains somewhat tertiary. Not much focus is put on how code is written and a developers’ skill to understand code by just glancing at it.
In layman terms, a product with good code quality delivers a good solution to a problem, not just in terms of UX but also from a developers’ experience. It makes it easier for developers to understand their own code and know how to refactor it without breaking anything. Good code quality reduces errors, bugs and unexpected behaviour. Even if some do creep in, it becomes extremely simple to find the source and fix them.
Maintaining a good code quality does not necessarily have to be a ‘review’ of the code once written. It is most effective when it is done from the very beginning. Choosing the right variable names, keeping the indentation constant and in compliance with the standards, thinking deeply about the weight of each ‘for’ loop used are some of the things that can be considered.
The scope of code quality is not just constrained within the walls of written code, but bleeds into the concepts of architecture as well.
- The book ‘Clean Architecture’ by Robert Martin refers to an important principle that is relevant for good overall quality. The ‘Open-Closed Principle’ states that the product in question should be ‘open’ for future updates and add-ons but the existing code should be ‘closed’ for edits while adding them. This is an essential principle that forces architects to think about the big picture and not immediate results.
- When you try to do many things in a place where only one thing should be done, bugs occur. While feature additions are being done, we try not to refactor code in a separate layer but revisit existing functions and implement them there, which creates anomalies in code..
- Dividing different functionalities amongst different modules is a good technique. So is creating multi-level designs with specific underlying features. Architectures like Plugin based architectures and layered (multi tiered) architectures help enforce these practices.
Eg: A button component is used for a login screen, where the functional and the UI parts are separate. Later, if an addition is required, say a spinner. The best way may appear to be adding the spinner in the button component but it isn’t so. It is ideal to keep the login button separate, the spinner separate and add a wrapper around them.
- Try not to repeat code. It is a bad practice to copy & paste code that is repeated multiple times through a project. Rather create modular & reusable code blocks that can be invoked and called, hence improving the overall performance and readability of code.
- There are tools that help enforce good code quality: Prettier & Husky are some of the most prominent. Prettier provides basic formatting and code structuring guidelines while Husky provides pre-commit hooks that can be run before committing code. Do check them out.
- Consider reviewing your code regularly. Different minds reading the same code can provide different insights into how to make it better, so share your code with your team and your leads and review it for each other. No better way to work than working together.
Impact on Business:
It should now be evident that quality code has a massive impact on business, in the way that good code quality identifies bottlenecks and improves performance of the product which makes for a good user experience. Well structured code leads to quick and efficient refactoring and feature-addition while maintaining stability on production, which enables growth and translates into good business. These impacts are usually seen on a larger scale but show signs on a small scale as well. The math is simple here:
The earlier you find defects and review your code for quality, the better the product becomes and the experience improves.
Speed Vs Quality:
It’s often debated if quick deliveries and shipped products are to be prioritized over quality code and standard management. While quality is always preferred due to the plethora of future possibilities it offers for the product, speed has its pros and cons too. Of course, you’re shipping early, the process is fast and the feedback is from the end users and real-time, but it can get really messy. A small bug in production can crash the entire product miserably. In the end, it comes down to choice, really, but it is advisable to spend a lot of time in architecting the product according to the requirements (which should be gathered in depth) and then following the devised architecture strictly.
Technical Debt: A Real Problem
Writing performant code is always tough and Technical debt is a nightmare that keeps product owners up for nights. Technical debt, in simple terms, is the additional cost involved in rework that was caused by choosing a potentially limited solution to a problem. Technical debt costs, not just in terms of money, but also time. One way to consider technical debt is to use To-Do comments wisely. Once a product is complete, revisit and refactor. Granted that this is highly dependent on constantly changing requirements but it’s a good way to avoid rewriting entire applications because of messy codes.