Sitemap

Recipe for Better Codebase

5 min readOct 7, 2023
Press enter or click to view image in full size
Unplash | https://unsplash.com/@nvte

Recipes for Failure

During my experience during the last 2 decades as a Software Engineer, I have played many roles entitled as a Software Engineer. Something I have mostly seen when it comes to maintaining a better Codebase is a failure.

Now if we look at any project in most organization, it start with the statement “Let's prototype this idea”. And that's not a bad approach. After all, you are selling functionality, not the SourceCode to the customer who pays you salaries. But what you should understand is If you keep on doing this “Let's prototype” approach, you will lose money instead of making a profit out of what you are developing.

On the other side of this, We find developers in organizations who plan for big-bang refactorings. They want to refactor the code using the refactoring literature out there. One common thing about this kind is that they always want the refactoring which they never find time for, because they are asking for whole sprints just refactoring, which is highly unlikely with market/business priorities. Based on that reason they just add more and more technical debt to the current Codebase. Now if they get the chance to do the big bang refactoring, most of the time end up with a few dozen regressions followed by another refactoring plan. It's not their fault, it's the nature of Software Development that they failed to understand.

Software Development is not like other kind of development in construction fields. When you construct a bridge, you don’t plan to change it every year, When you construct a building, you don’t plan to add and expand the building every month. But in Software, you always evolve it to match the market needs. Software is a living organism, rather than a static entity.

Now there is another mistake most Software Developers make, and That is “ReWrite”. Rewriting Software to get rid of technical debt is a risky move unless you are rewriting a very small microservice which you can do within one sprint. I have been in this group as well and failed utterly after spending nearly 9 months trying to rewrite while trying to keep up with the new changes that are getting added to the production version. The reason is even if you rewrite successfully, the design might need changes again to adapt to new market trends, which might put the time spent on refactoring and designing a waste.

Better Recipe

We said that the Software is like a living organism. They change with the market changes that they are made for. Some bugs are being discovered. Some features evolve, so get change after getting feedback from end-users. The understanding of what we thought was a good solution changed over time. So if you think a ReWrite/Refactoring might resolve your issues, it could also become your next issue.

So let's look at an approach that could give you a balance of, releasing new features while you improve your codebase at the same time without spending time on a Total ReWrite/Refactoring.

Let's assume you have a module/service that looks like the below image

Press enter or click to view image in full size

As you can see you have somewhat of a spaghetti codebase above. So in the next few illustrations, you will see how we approach improving our codebase while adding new features/APIs and maintaining current features/APIs

Press enter or click to view image in full size

In the above state, we have spent some time refactoring our data access-related code and encapsulating it in its layer while fixing some issues related to persistence in this service. This could be seen as a persistence, repository, or DAO layer. The changes can be seen in blue.

Press enter or click to view image in full size

Now in the above, we see that we have been working on adding a new API in yellow, but we found that another API in the service does share some logic that we wanted for this new API as well. In the illustration, you can see the shared logic in green. So instead of duplicating, we spent some time refactoring only that part so the shared logic can be used both on existing and new API. We also restructured part of the existing API so that we have code components that follow SRP (Single Responsible Principle). There are good design patterns out there that can help you in this, But the main concepts you should strive after are Abstraction, Loose Coupling, and High Cohesiveness like basic concepts.

Press enter or click to view image in full size

Now in the above, we see that we have made some changes to the first API which is the first one from the top. While we were doing these changes we spent some time continuing on the previous refactorings we did in our previous steps. While doing those changes we saw that we could use the previously extracted shared logic too. So by now, we should have refactored most of our service to achieve loosely coupled components that adhere to SRP.

You can take another round and do some more refactoring when you touch the code where it fits. This is not going to be a one-time task, it's a recurring task, that's why we say Software is a living organism that needs routine care.

Garnish

Now some of you might say the above recipe is a utopian approach. Some might point out famous quotes from literature about refactoring to prove this is infeasible. I have heard it a few times developers and non-developers have said so.

Well to perform or carry on a planned refactoring like this, you need to have a good team who works towards and march towards a common goal. They must value writing quality code and time to market over just/only pleasing the stakeholders.

The above example is based on such a plan that I and one of my team made some time back on a very legacy codebase which were in bad shape when it came to adding new feature or taking those services to the next level. It helped the team perform micro-reactorings while shipping value from the service. Using tools like SonarQube helped to make sure we were on the right path according to our plan.

So if you have a codebase that is in somewhat bad shape, give this approach a try and Let me know how it went.

--

--

Responses (2)