Navigating Technical Debt
Tags: csharp, python, git, technicaldebt
Published: 2024-05-04 02:06:34

We don't spend enough time doing maintenance! We have too much legacy code! We only build new features and never cleanup the old things we made! We have too much technical debt!
Sound familiar? If you have been involved in any meaningful software development project – especially one that is large – you will have heard complaints like this. 
It's a topic that many software developers (including yours truly) are passionate about.

I would be willing to bet that if you surveyed random developers at a conference, you would find that the majority of them consider technical debt to be a significant problem in their organization.
I would also be willing to bet that they could not agree on **what the problem is** and **how to address it**.
The issue is further complicated by the fact that many businesses seem to not care about tech debt.

In this post I want to explore the idea of technical debt. What is it? Can we measure it? What can we do about it?

## What Is Technical Debt?
The term is used to describe things from "we don't use the shiny new framework" to "this code is not written in the style I like" and even "I inherited the code from someone else".
Let's start by looking at Ward Cunningham's original definition:

> Shipping first-time code is like going into debt. A little debt speeds development so long as it is paid back promptly with refactoring. 
> The danger occurs when the debt is not repaid. 
> Every minute spent on code that is not quite right for the programming task of the moment counts as interest on that debt.
> Entire engineering organizations can be brought to a stand-still under the debt load of an unfactored implementation, object-oriented or otherwise. 
> 
> *- Ward Cunningham*

This definition focuses on technical debt being a trade-off **when developing new features** and that **it is not always bad** as long as its addressed promptly. 
The problem though is that unlike financial debt, who is responsible for making sure an organization can handle more technical debt?
Can an organization be "technical debt" bankrupt? 
When organizations start thinking of this in terms of "debt" they quickly realize that there don't *seem* to be any consequences of the debt, so they ignore it.

Steve Freeman (whose work I first encountered in the wonderful book [Growing Object-Oriented Software, Guided by Tests](https://github.com/sf105/goos-code)) describes technical debt as an ["Unhedged Call Option"](https://higherorderlogic.com/programming/2023/10/06/bad-code-isnt-technical-debt-its-an-unhedged-call-option.html).

This definition highlights the **unpredictability of cost**.
Unlike debt – where we know what the interest rate will be – options could be infinitely more costly than doing the work in the first place.
I like this definition because it brings forth this idea that the cost can become due suddenly and without warning, and we need to understand where to focus our efforts because the "debt" is a disaster waiting to happen.

## Lensing To Understand Technical Debt
Michael Feathers has a great post – [Lensing to Understand](https://michaelfeathers.substack.com/p/lensing-to-understand) – about how we change our focus to understand a system.
We focus on the high level system to identify potentially interesting areas and then drill down into details to investigate them.
Once we have a better understanding, we zoom back out to see how it affects the system as a whole.
The idea of "lensing" is really important when it comes to understanding technical debt.

In previous attempts of tacking technical debt, I have made the mistake of *starting* with a focus on very specific parts of a system.
Starting with a systems view and then drilling down into the details may be a better way to understand the system.
Where do people encounter the most issues?
Are some parts of the system riskier than others?
What parts of the system are most likely to change in the future?

These are the kinds of questions we need to be asking.
Too often we focus on bits of code and forget the context of the systems it's used in – which is extremely important.

So how do we identify risks in our codebase?
Adam Tornhill has a great talk on ["Prioritizing Technical Debt"](https://www.youtube.com/watch?v=w9YhmMPLQ4U) where he talks about how we can use metrics to identify risks in our codebase.
If we have a way to find out **where to focus our efforts** we can get a lot more value out of the work we do – **allowing us to ship quicker and build high quality features**.
I really liked this talk and I recommend watching it.

Adam has a few metrics that he uses to identify risks:
* **File Hotspots**: Files that are changed frequently
* **Method Hotspots**: Methods in hotspot files that are changed frequently
* **Complexity**: Files that are hard for humans to understand

If we find places that meet all three of these criteria we have a high risk area that we should focus on.

---
Read the full version of this post on my blog: https://pureooze.com/blog/posts/2024-03-29-navigating-technical-debt/