I saw this tweet recently and it sparked a few thoughts as it neatly gets to the heart of the biggest challenge in software – getting to done.
P1: Aren't you ashamed of writing code like this?
— Kent Beck (@KentBeck) October 31, 2019
P2: What do you mean by "this"?
P1: Sky-high cyclomatic complexity, inconsistent naming, & duplication.
P2: Oh, I thought you meant "profitable", and the answer is no I'm not ashamed.
In my experience there is very often a tension on any sizable software project between the desire of the business to get the software in front of customers as quickly as possible and the engineering team’s desire to ensure the code and architecture is of a high enough quality to make refactoring, scaling, testing and addition of new features as easy as possible. Both desires are equally valid.
The business needs to expand market share, ship code, have happy customers and get paid. Possibly by being first to market. Possibly because commitments and contracts have been signed promising a hard delivery date.
Equally developers understand the value of flexible architecture, code that is easy to refactor, test and debug. Further developers know that without these things code becomes harder to work with, meaning quality is hard to ensure, which leads to bugs and delays in delivery and ultimately unhappy customers.
The tension comes from the assumption on both sides that the other should see their view as perfectly obvious and correct. Both tribes are worrying about the same thing from a different view point. Simplistically:
- The business worries that if the customer doesn’t get their software, we won’t get paid and we’ll be out of a job
- The dev team worries that if the software isn’t right we’ll be shipping slow buggy software, we won’t get paid and we’ll be out of a job.
It is in the middle of these two tribes and this argument that the senior/lead developer will find themselves. And it is here that both sides have to communicate and trust each other.
Communication
At the start of the project we could agree (simplistically):
We must ship this project by June 2020, otherwise we lose the contract to our competitor. We need to make some pragmatic decisions, take on a certain amount of technical debt. Once we deliver we won’t promise any major new features until the technical debt is resolved.
Trust
Regarding trust. The business needs to trust the team that they will deliver and make the necessary pragmatic decisions. The developers need to trust that the business will allow them the necessary space to address the technical debt.
Profit
Which takes us back to the tweet. Code that is profitable but with an amount of tech debt is acceptable as long as each side understands the reasons and the trust exists to resolve as/if needed.
Faust
Unfortunately in many software projects the above turns into a Faustian pact for the dev team. Reluctantly they allow the technical debt to build up trusting that time will be given to resolve it. In the meantime the business signs more deals, or demands new features with harder deadlines and the project becomes exactly what the dev team feared - unwieldy, slow and buggy, and stress increases.
Excellent teams and businesses understand this, and ensure that both deadlines are hit and code quality is high, with time allowed to address technical debt. In the end it’s only the excellent teams that will succeed.