You schedule sprints that do nothing but clean up the previous sprint. You are told that features you feel are critical to the product “simply can’t happen”. You watch feature after feature ship late and then get long bug reports.
However, you have not been idle. You’ve contracted process and technical consultants. They gave you answers and you got the green light to implement them. Things did improve, but your bottom line issue of buggy and late deliveries continue to happen.
These deep frustrations are not because you have “bad” developers. In fact, they are saving 99% of the thousands of risky decisions they are faced with each day. The reality is that your problems are caused by risk in the code. Your delivery quality and cadence are only as good as your worst code.
The ultimate problem is that your developers need to trust the code they are reading. That low productivity you’re seeing is because they can’t trust what they see and must cautiously pick through the code. And because the code is not trustworthy, they will always make errors based on wrong information, resulting in bugs.
Solutions that DO Help
You’ve done your due diligence and found solutions that are reliable and have shown improvement. TDD, CI/CD, pairing, mobbing, replacing the legacy system, microservice architecture, Kubernetes, and telemetry. These are excellent techniques for leveraging and maintaining a healthy codebase.
And yes, you’ve seen that these do discover and address quality issues in your less healthy codebase, but the total technical waste continues to grow and now new struggles have shown up:
- Cross-service complexity
- Untestable code
- Re-write never catches up with legacy system
- Debugging in production
- Live site issues
- Ever-longer bug backlogs
But in the Real World
The problem is that each of these solutions works great when your code is already healthy. They were not invented to fix code; rather, they were invented by teams with already healthy codebases in order to maintain its health and create new healthy code. As a result, each of these techniques assumes two things:
- your code is easy to change, and
- you don’t have any bugs that would be possible to detect before release.
Achieving those requires that your code is trustworthy and easy to read.
Your developers want to come into work, trust that the code they’re looking at is doing what it says, and easily read how. Then they want to add a feature while keeping it trustworthy. That is how it’s supposed to work.
How Big of a Problem Is Readability?
As a comparison, everyone wants concise emails with clearly titled subject lines, but instead, we get an overwhelming flow of reading. Topics are split among many emails, each of which jumbles it with other, unrelated topics. Sometimes we can’t even make sense of the grammar in a single email. But if we ask for clarification, we may end up in a 20 email thread. Or they don’t respond. Now we need to track them down. It’s easier to just guess. Or ignore. As the inbox fills, we embrace the joy of folders and hide the terrifying backlog that eventually becomes impossible to truly clean up.
This is what the developers face, only they share the inbox with all their colleagues.
This is painfully oversimplified, but you get the picture. It’s exhausting and unrewarding. Additionally, reading emails isn’t productive as it hurts our ability to get work done. The same applies to developers wading through the code. Over half the time spent on completing stories is simply reading the code, which is the responsible thing to do when you can’t trust the code and want the story to succeed.
Can we Afford to Make the Code Trustworthy?
The typical codebase has millions of lines of code. How do you make all of that trustworthy? Not all at once. Instead, we take on a 3-part solution.
- Improve developer skills to read untrustworthy code.
- Perform the reading in a way that leaves the code trustworthy after the first read-through.
- Incrementally fix each piece of code as you need to read it.
Implementing this successfully requires a uniform method for developers to read and fix the names, in a way that guarantees no new bugs. This makes all teams capable of refactoring in a safe way so that they can trust the code. But why would we refactor (code without adding a feature) since the act of coding risks adding bugs?
We Need a New Way to Refactor
Most teams’ refactoring approach has a small chance of adding bugs, but one refactoring technique, Disciplined Refactoring, is as safe as any other way of reading code. It will never change any behavior, even a behavior the developer is not aware of. It does not depend on tests to provide safety, so it works even on untested (and untestable) code.
Because Disciplined Refactoring is safe, it can be used while reading code. Our uniform practice to read untrustworthy code is simply:
- Make it trustworthy, using Disciplined Refactoring.
- Then read the easy code.
Even better, on average, the cost to refactor untrustworthy code is much less than the cost to read the original code. Thus, this approach both decreases the cost of today’s story and makes the code trustworthy for next time.
We Need to Not Add to the Workload
Adopting most techniques has a high cost. The traditional implementation is to hire a technical consultant, teach the practice to a few of the teams with pristine code that isn’t realistic, and then work on ways to spread the technique to other teams. The industry has seen this work well enough that it is an accepted practice. However, it is a disruptive and costly practice.
Our implementation is to integrate micro-learning methods into the workload with one tiny habit shift at a time. By practicing the new skills in a ½ day training mob in their codebase, they get the experiential exposure to the new ways of reading and naming code. Then over the next weeks, the developers take each tiny technique and practice it every time they read or name code. In this way, learning to make the code trustworthy has not become a high overhead cost for the organization. Developers are getting the code to a trustworthy state one method at a time with each story they write.
What You Can Do
The first thing you can do, especially as a non-coder, is to facilitate the Insight Loop Workshop, a compilation of small habits that gets developers started on the journey towards trustworthy code. Built as a cooperative effort between technical expert Arlo Belshee and learning designer Marian Willeke, also a non-coder, this workshop provides a step-by-step facilitator guide, the expert videos for when developers object, and a collaborative Slack channel for support from Arlo.
However, this is only the workshop, so a way to extend the return is to adopt the habits with structure. We offer different levels of investment for teams fully adopting the Insight Loop, whether they choose to self-adopt, hire coached assistance, or adopt well beyond the Insight Loop (Code by Refactoring program).
And why go through all of this? Because you want to improve productivity, write fewer bugs, and code more safely.