Starting out the development of a product is very exciting. You’re able to focus your attention on all the small details and you dedicate time for designing and thinking forward. It’s your chance to do it right. You can do things just the way you want it to be done — using short and readable files, writing clearly defined and named functions and variables, using the latest frameworks and implementing cool features in record time, all while using principles such as SOLID, TDD and Clean Code.
Fast forward a couple of years, and now there’s a team of software engineers. You are all adding thousands of code lines every week and you simply can’t keep up to the same standards you’ve held yourself to at the beginning.
Now, maintaining the code has become a challenge. You have hundreds of modules, dozens of APIs and a tens of thousands of code lines to maintain. Developing new features takes longer and the training period for new engineers has extended significantly. If you had less code, it would be much easier to maintain.
Code maintenance is not the only reason to shorten your code.
Why You Should Keep Your Code Short
Easier to Read and Understand
Shorter code is much clearer because it will usually contain modules that do only one thing (single responsibility). In such concise code, the core tasks in each function/class surface, and their logic is coherent.
Less code means there is a smaller risk of bugs, which means a higher quality code.
Enables Better Testing
A long code means more tests. Writing tests takes time, and running them can also take valuable time. On the other hand, having code that is untested is always a risk for a faulty product (aka Schrodinger’s Code). By removing unneeded tests you can save valuable time and help maintain a situation where tests (unit tests, load tests, functional tests, etc.) are being run frequently by all developers.
Maintains Developer Focus
A shorter code ensures developers focus on what is needed and which features give the most value to your customers. The code contains only what is actually used and can be reenforced, without redundancy.
If your code is already long, the way to make it shorter is to delete parts of it. This is valuable for making your code more maintainable and for being able to understand which parts of the code are relevant and which aren’t. But, let’s face it, it’s also fun. Deleting mass amounts of code is satisfying and enjoyable (especially if it was written by someone else).
Identifying the Right Code to Delete
Identifying code that can be safely deleted is not always easy. The most common case of code that can be safely removed is components that are no longer needed. They might be commented out (easiest to spot) or disabled (are not called anywhere in the code) and are usually left there for some day in the future when someone feels confident enough to delete them.
Remember the feature that was disabled “just for a couple of days” and is still disabled months after? The form that was replaced by a newer version? The UI that is no longer needed and is still waiting for the new UI to “feel mature enough” so it can be deleted (even though the new UI has been in production for the last couple of months)? These are all examples for code that is no longer needed and can safely be removed.
This is especially true when you’re working around legacy code or code that was written a long time ago. A lot of people won’t delete a feature but would rather just disable it, “just in case” it might be needed in the future. 99% percent of the time — you definitely won’t need it. For the 1% — that’s what source control is for.
Code Deleting Best Practices
Be a “Good Samaritan”
Do you know the “Good Samaritan” principle of software engineering? It’s “always leave the code in a better shape then how you found it.” When going over a module to find the right place for your new code, take a second to understand what else the module does and make sure that the existing code is still relevant. Found something that is no longer needed? Delete it!
Refactor, don’t just add
Going to extend the capabilities of a module? This module was built to meet specific requirements, and these requirements have now changed. See if you can refactor the module to better answer the new requirements, in the most minimal way possible, getting rid of code that is no longer necessary .
Keep in mind that when deleting code that is no longer necessary you should also delete all other “leftovers”:
- Any imports or calls to this code (UI and BE)
- Referencing APIs
- Models that are used only by this code
- Tests (Mostly Unit, maybe some end-to-end)
- The old code itself
Test the new code
Before the committing the deleted code, run end to end tests on your new code. If something important is deleted, the tests will let you know.
How to Start Deleting Code
Making sure unnecessary code is constantly removed is a not a trivial task. It requires engineers to fully understand a piece of code (that in most cases, was not written by them) and feel comfortable enough to remove it.
Companies can also provide trainings and set team standards for when handling legacy code. For example, they can encourage engineers to cover as many of the main scenarios as they can with end to end tasks (and delete unnecessary code) and to schedule a ‘code cleanup’ event that includes training and a lot of time of actually reviewing and cleaning up legacy code.
It’s easiest to start with ‘Being a Good Samaritan’: identifying and removing useless code is easiest when you’re already focused on specific areas of the code.
Once you get the hang of it, it will become second nature to you and the results will be impressive.
At Otonomo, in recent months only 18% of the new code actually increased the size of our codebase. This means that for every 10 lines of code we wrote, we’ve deleted 8. This is a great statistic and definitely something that we can, and will, keep in mind when moving forward.