Why you’re losing the battle for high-quality software
Every day you go to work and you have to fight. Your boss wants to deliver features as fast as possible, and so you have to either argue for best practice, or work extra hours to do things the right way.
You need to fight for readable and maintainable code. And you need to fight for reusable code. And you need to fight for tests.
And you fight and you fight and you fight, and you keep on losing.
It doesn’t have to be this way. Software development doesn’t have to be a fight. Strange as it may seem, in this game the only winning move is not to play.
Instead of playing “Let’s Write High-Quality Software”, there’s a different and better game you can play: “Let’s Solve The Problem”.
Avoid false dichotomies
The problem with the game of High-Quality Software is that it’s based on a dichotomy, with only two options: low-quality and high-quality. I started this article with another dichotomy: arguing with your boss vs. working longer. And a lot of technical discussions quickly devolves into dichotomies, e.g.:
- Shipping features vs. fixing technical debt.
- Testing your code vs. coding quickly.
Dichotomies are tempting, and perhaps even built-in to the way we understand the world: there’s a left hand and a right hand, a wrong way and a right way. But there’s nothing inherently superior in just having two choices. In fact, all it’s doing is making you a worse engineer, because you’re focusing on arguing instead of focusing on solving the problem.
To combat this tendency, Gerald Weinberg suggests the Rule of Three: always consider at least three solutions to any problem. Let’s start with our first dichotomy: arguing with your boss vs. working longer hours to do things the right way. If there’s a third choice, what might it be?
Stop arguing, start listening
When your boss or colleagues argue for a specific design, instead of telling them why they’re wrong, listen to their reasons. Behind every design proposal is a set of goals, motivations, presumed constraints: those are the things you need to address. If you criticize their proposal based on goals they don’t care about, you’re not going to get anywhere.
So first, listen.
Once you understand why they want what they want:
- Consider more than the initial two choices, their proposal and your initial reaction.
- Try to find a solution that addresses both your goals.
- Explain you thinking in ways that are relevant to their goals, not just yours.
Example scenario: testing
Your boss proposes writing code without unit tests. Why? Because they want customers to be happy. Since customers have been complaining about how long it takes for new features to be delivered, your boss believes this is one way to speed up delivery.
You want to write unit tests. Why? You want code to be maintainable over time.
Merely arguing for unit tests isn’t going to address your boss’ concerns. But if you look past the initial false dichotomy, there are other solutions to consider. For example:
- Investigate why customers aren’t getting features quickly. Perhaps the bottleneck isn’t due to how fast you’re coding, but elsewhere in the delivery process (you don’t do frequent releases, customers need to upgrade manually… there could be many reasons). Fix that, and you will have time to write unit tests and ship quickly.
- Figure out places where bugs would be costly to customers, explain those costs to your boss, and propose unit testing only that part of the code.
- Investigate customer needs in more detail. Perhaps existing customers are complaining about feature delivery, but you’re also losing many customers due to bugs.
- Suggest using tools that will speed up test writing enough that the additional time won’t bother your boss.
- Suggest limiting unit test writing to a predetermined amount of time: “this will only add 4 hours to a one week project”.
No doubt there are many more potential solutions to the standoff.
There’s always another solution
There is almost never a single correct solution to any problem, nor a single best solution. You can solve problems by relaxing unnecessary constraints, by focusing on different levels of the situation (organization, process, code), by redefining the problem, and more. Worst comes to worst, you can address many problems by switching jobs; different people like different environments, after all.
So don’t try to win technical arguments, and in fact, don’t treat them as arguments at all. When you disagree with someone, take the time to listen, and then try to come up with a solution that address their concerns and yours. And if your first idea doesn’t do that… it’s time to come up with a third, and fourth, and fifth solution.