Confronting Incompetence: How to Stop Shipping Bad Code and Tackle Technical Debt Effectively

TL;DR

Shipping bad code is not just technical debt but a sign of deeper issues that teams must address by committing to quality and accountability. Key actions include enforcing thorough code reviews, investing in automated testing, and making regular refactoring a habit, while also actively identifying, prioritising, and allocating time to pay down technical debt. Development managers should ensure their teams distinguish between technical debt and poor practices, and dedicate resources to maintain a healthy, sustainable codebase.

26 November 2024
Written by Martin Hinshelwood
3 minute read
Subscribe

I’ve been in the trenches of software development long enough to know that we all have our moments of weakness. I’ve written bad code and shipped it. And let’s be clear: that’s not just technical debt; that’s incompetence. It’s a hard truth, but one that we must confront if we want to grow as developers and as teams.

Understanding Technical Debt

In the context of a competent team, we can differentiate between known technical debt and unknown technical debt. Known technical debt is the stuff we acknowledge, those areas of our codebase that we know need refactoring or improvement. On the other hand, unknown technical debt lurks in the shadows, waiting to rear its ugly head when we least expect it.

But there’s another layer to this conversation. We often conflate technical debt with simply shipping bad code. This is a dangerous mindset. When we knowingly make poor choices and then choose to ignore them, we’re not just accumulating technical debt; we’re actively undermining our own work.

The Cost of Bad Code

So, how do we address this? The first step is to stop shipping bad code. It sounds simple, but it requires a commitment to quality and a willingness to hold ourselves accountable. Here are a few strategies that have worked for me:

  • Code Reviews: Implement a robust code review process. This not only helps catch issues before they make it to production but also fosters a culture of collaboration and learning within the team.

  • Automated Testing: Invest in automated tests. They serve as a safety net, allowing you to catch regressions and ensure that your code behaves as expected.

  • Refactoring: Make refactoring a regular part of your development process. Don’t wait for a major release to clean up your code; do it incrementally.

Prioritising Technical Debt

Now, let’s talk about the technical debt we do have. It’s crucial to prioritise paying it back. Think of technical debt more like an unhedged fund rather than a credit card debt. Most debts are secured against something tangible. For instance, if you stop paying your mortgage, the bank can repossess your house. In contrast, technical debt is more abstract. If we ignore it, we risk losing the very foundation of our codebase.

Here’s how I approach the repayment of technical debt:

  • Identify and Document: Keep a running list of known technical debt. This should be a living document that evolves as your project does.

  • Prioritise: Not all technical debt is created equal. Some issues will have a more significant impact on your project than others. Use a scoring system to prioritise which debts to tackle first.

  • Allocate Time: Make it a point to allocate time in your sprints specifically for addressing technical debt. This ensures that it doesn’t get pushed to the back burner.

Conclusion

In conclusion, we must take responsibility for the code we ship. By recognising the difference between technical debt and incompetence, we can make more informed decisions that lead to better outcomes. Let’s commit to quality, prioritise our technical debt, and ultimately, create a codebase we can be proud of. After all, the goal is not just to ship code but to ship code that stands the test of time.

Smart Classifications

Each classification [Concepts, Categories, & Tags] was assigned using AI-powered semantic analysis and scored across relevance, depth, and alignment. Final decisions? Still human. Always traceable. Hover to see how it applies.

Subscribe

What to read next

Video Engineering Excellence

Mastering Technical Debt: Strategies to Transform Challenges into Opportunities for Your Development Team

Explains technical debt in software development, its impact on teams, and practical strategies to identify, manage, and reduce it for …

Watch video
Video Engineering Excellence Technical Leadership

Navigating Technical Debt: How to Transform Challenges into Opportunities for Quality and Efficiency

Explains how managing technical debt and distinguishing it from poor quality can boost product efficiency, reduce costs, and support …

Watch video
Video Product Development

Transforming Technical Debt: Unlocking Innovation and Value Through Quality Product Delivery

Explores how managing technical debt enables faster delivery, higher product quality, and greater innovation, highlighting strategies for …

Watch video
Video Product Development

Transforming Technical Debt: Unlocking Opportunities for Innovation and Value

Explores how addressing technical debt boosts innovation, team morale, and value delivery by enabling agile development, better products, …

Watch video
Video Technical Leadership Engineering Excellence

How to Tackle Technical Debt Without Halting Progress: Smarter Ways to Keep Your Team Moving Forward

Struggling with technical debt? Discover practical ways to tackle legacy systems, boost team morale, and deliver value, without grinding to …

Watch video
Signal Engineering Excellence Technical Leadership

There no such thing as "good" technical debt

Technical debt always harms productivity and system stability. Ignoring it leads to inefficiency and risk, making it essential to address …

Read article