Technical debt is one of those things that software development teams simply have to live with. It’s so omnipresent in the development world that we have tackled it before in The Daily Bundle, especially exploring ways to prevent it and to pay it down. But every time we’ve discussed technical debt before, we focused on how the team could deal with it.
Naturally, that’s the best approach to do so, since the most efficient way to manage technical debt implies a group effort led by a well-defined plan. Yet, that method leaves a gap that we haven’t explored before: Is there something individual developers can do to help with technical debt? Fortunately, there is.
What Is Technical Debt?
Before getting into the ways in which any software engineer can help with technical debt, I think it’s important to define what technical debt actually means. We use that term to refer to the process through which a development team chooses a particular development route over another to satisfy pressing needs or to meet specific goals. In a sense, technical debt is the act of compromising when coding.
Thus, an engineer might choose to write a function in a certain way that allows for the software to execute that function right away, but, by doing so, they are blocking a further sophistication of that functionality.
Technical debt can occur in 3 main areas:
- Application (the software)
- Infrastructure (operating systems and environments)
- Architecture (hardware)
The reasons why a development team might be willing to incur technical debt can differ. Most of the time, developers choose to sacrifice certain good coding practices to meet a delivery deadline. That mostly happens when a development team is on a tight schedule where postponing the delivery to work on the function would translate into increased costs or an unacceptable time to market.
While the idea is to aim at the lowest possible level of technical debt, the reality is that having zero debt is impossible. When an engineer chooses a particular way to code a function, application, or project, they are making compromises they’ll have to deal with in the future.
Thus, technical debt feels like financial debt—you borrow something that can be useful today knowing you’ll have to return it later on. In the case of development, that something you borrow is proper code. As it happens with financial debt, technical debt also has interests: The longer you stick to the code that generated the debt, the more you’ll have to “pay” later on (in other words, the more you’ll have to rework your code to adjust it).
Now that we’ve gone through the definition of technical debt and its implications, let’s see how each developer in a team can help tackle it, which mostly consists of 3 distinctive actions.
1. Make the Debt Visible
There’s a nasty habit in certain development teams that has engineers tiptoeing their way around their code issues. Everyone knows that the issues are there and everyone is impacted by them, but everyone keeps moving forward while looking the other way. Unfortunately, doing that only increases the interest the team has to pay for that debt.
Think about it. If a specific module is underperforming because of a lack of proper coding, then the team has to double its efforts to compensate. That means that engineers will have to find workarounds and patches to keep the development going. The obvious solution would be to just pay the debt, but that’s a decision the PM has to make—and sometimes they aren’t aware of those problems.
How could that happen? Most of the time, problematic code goes unnoticed by PMs because engineers don’t give it enough visibility. The team gets used to working around the problem to the point where they forget all about it. That’s why the best thing engineers can do is be vocal about the debt that’s hurting their performance.
Bringing constant attention to technical debt will make it harder for it to fall through the cracks. In fact, a guaranteed visibility will keep the PM’s attention on that technical debt in such a way that they can devise the necessary steps to deal with it in the proper moment—before the interest gets too big.
2. Refactor Code When Implementing New Features
A developer reading this might think that refactoring code while working on a new feature is a terrible idea. But hear me out: Doing that can increase the application’s stability while also preventing new interests from ever emerging.
For example, a team working on a new web app might devote part of their time to squashing certain bugs. As they flesh out the web app, more and more bugs appear on top of the older bugs. After a while, the team will be forced to stop development of new features to focus on refactoring the code to get it to function properly. That can significantly derail a development project (not to mention the added costs associated with the delays).
So, why not be proactive about those bugs? Instead of dealing with them once they have piled up high enough, each engineer could push for a smaller refactor when bugs are few and more easily manageable. You could argue that doing so would also bring delays to the development—and you’d be right. However, the delay caused by a series of small refactors could end up being smaller than the one caused by one big refactor.
How can an engineer know when a small refactor is the best way to go? Unfortunately, there isn’t an exact formula for it. Experienced engineers surely have it easier, but developers of all skill levels and experience should keep this option in mind and talk it over with their PMs when in doubt. They’ll quickly find out that there are many times when delays are really worth it, as they prevent technical debt from escalating.
3. Elevate Your Coding Quality
I’ve said above that technical debt is unavoidable. Yet, that doesn’t mean that engineers can use it as an excuse to neglect good coding practices. Yes, they will have to deal with technical debt no matter what, but the burden will be significantly lower if those developers follow good coding practices.
The reason why is fairly evident: By using bad coding practices, engineers are introducing more and more debt into the system. Ultimately, bad coding can lead to a bug entanglement that will be harder to manage and solve. Thus, engineers should avoid practices like putting out rigid and tightly coupled software, using fragile code that breaks at the minimum change, or pushing untested code for edge cases into production.
I’m not going to get into what good coding practices look like (we’ve already covered that front in this article). But I’m going to insist on the need for elevating coding quality. Good coding practices are the root of the highest quality software (the only kind of software that you should be aiming for).
Individual Engineers Can Make a Difference
While these 3 actions might not seem much at first, the reality can definitely show you that technical debt gets more manageable once engineers in your team start to embrace them. It’s important to remember, though, that these actions shouldn’t come at the expense of a strategic plan to deal with technical debt.
These actions are a supplement to that strategic plan, not a replacement. And while they won’t get rid of all the technical debt your development team will incur when working on your projects, they can certainly make it more manageable. The results will be a more efficient team that can meet deadlines more easily and put out more robust and high performing applications.