Technical debt "management"
Dear all,
How a team could identify technical debt?
Which could be some ways/techniques to reduce it in practice? Could refactoring be one?
Thank you very much in advance for your insights!
Technical debt is any kind of deficiency in internal quality. This is a broad definition and many things can be classified as technical debt. The technical debt quadrants provide a framework for thinking about different kinds of technical debt and teams may be able to identify some of them.
In the moment, the team can see if they are deliberately introducing technical debt, whether that's reckless and knowingly making poor decisions (like skipping thinking through design, not writing automated tests, not refactoring) or prudent (delivering less than optimal designs or lower quality product in favor of faster feedback on the direction). When these decisions are made, the team can always record a note to go back and revisit them - rethink the design and refactor to improvements, adding the automated test coverage, and so on.
Inadvertent technical debt is harder to spot in the moment. The team doesn't know what it doesn't know. Sometimes, doing additional work can reveal a better way to do past work. As soon as the team learns that there's a better solution to a past problem, they can place revisiting that past work on the backlog. However, if the team hasn't yet recognized that their past decisions let to deficiencies in internal quality, they won't be able to express the concrete improvement to the system. Some of these inadvertent technical debt items may reveal themselves as impediments that slow development but don't have an obvious improvement without a deeper understanding of the technical context of the system.
How a team could identify technical debt?
Many modern engineering teams use a tool such as SonarQube, which will analyze and inspect code for technical debt. It will report code coverage, cyclomatic complexity, duplicate code, cohesiveness, coupling, and more. This will help your Developers with refactoring.
Which could be some ways/techniques to reduce it in practice? Could refactoring be one?
The Developers could add code reviews, pairing, and mobbing practices to the Definition of Done. But you should be asking them, right? If there is already debt in the product, they could work with the Product Owner to make it transparent on the Product Backlog and come up with a plan to pay it back.
Both @Thomas and @Chris gave you advice I was going to give. But there is one piece neither of them mentioned. It goes to the "how can they remove it" question.
Technical debt is a change that needs to be made in order to improve the product. It is very much like a product enhancement. Both of them add negative value (enhancement by not being done, technical debt by existing) and they add positive value (enhancement by being implemented, technical debt by being removed). So I coach that any known technical debt should be represented in the Product Backlog. The Developers should work with the Product Owner to help them understand the value statement. Then the Product Owner will be able to order it appropriately in the Product Backlog and convey why it is being worked on to the stakeholders.
How a team could identify technical debt?
With a Definition of Done that truly reflects the quality needed for work to be immediately usable. The i's must be dotted and the t's must be crossed. That's the key. Any outstanding work failing to meet this standard may be referred to as technical debt.
Which could be some ways/techniques to reduce it in practice? Could refactoring be one?
There's a 3 part strategy:
- Plug the hole with a Definition of Done which assures work is usable. This stops more technical debt from pouring in, because from this point on the Developers are being good and true. Refactoring could be an example.
- Capture the technical debt that has been incurred on the Product Backlog. This must tell the truth at all times about how much work is currently believed to remain for the Product...including any technical debt.
- Pay off a certain amount every Sprint until the debt is drained. Try to avoid starting new initiatives which will incur losses due to context switching.
Managing technical debt involves a delicate balance between quality and avoiding gold-plating. A well-crafted DoD can mitigate some forms of upfront debt, but tools like mentioned by Chris and technical competencies are also needed. By adhering to the YAGNI principle, Teams can avoid unnecessary complexity and work, reducing technical debt and increasing the codebase's maintainability. It urges developers to concentrate on what is essential, thereby conserving resources and keeping the software as simple as possible for as long as possible.
A proactive mindset, emphasized by a test-first strategy and regular code reviews, can maintain quality from the start. Tools like code linters and test coverage metrics can spot issues. Competencies evolve, revealing what can now be considered "inconstant" technical debt.
Refactoring is crucial for tackling debt. Adequate automated testing must precede any refactoring to validate code changes. This process is flexible and adaptable to both developers' insight. Sometimes, more extensive architectural redesign may be required.
As a Scrum Master, I would focus on the non-technical facets of handling technical debt. I'd promote awareness of its impact, ensure time allocation for its reduction during sprint planning, and enhance communication between Developers and stakeholders for prioritization. The aim is to make technical debt transparent and managed proactively, ensuring that quality remains consistent throughout the Sprint.