> “Creating technical debt” is about not spending the time to find a good way to initially write the code, leaving it to a later point in time.
This is the wrong way to describe and explain technical debt. It fails primarily to sell the wrong idea that technical debt results from incompetence or failure to do a good job.
The truth if the matter is that in software development the absolute best solution to a problem is to provide an implementation that meets current requirements and is implemented as fast as possible. Overgeneralizing is bad code. Abstracting implementation details is a code smell. Proposing an implementation that considers additional design requirements and constraints is goldplating a solution, thus the sign of a mix of incompetence and wasted effort.
But then what if requirements change? Ah, the delta between the fast and good solution for the initial problem and adapting it with quick fixes to address the new requirements is precisely where technical debt pops up.
I think you’re being downvoted because your comment seems, especially in the first two paragraphs, to imply that:
- competent programmers who do a good job write the best code in the shortest amount of time
- more time always leads to worse code (unnecessary abstractions, handling non-existent requirements)
If you do know of programmers who are competent and generally do a good job, you can disprove this claim easily: Have them write a solution to some problem in a given amount of time, then have them spend more time on it.
Often you can see that they actually achieve a “cleaner” solution, including removing unnecessary abstractions.
I do agree with you though that some tech debt is caused by a lack of skills/experience. I guess we could further divide tech debt between intentional (the one I wrote about) and unintentional (the one you seemed to focus on in your comment).
> - competent programmers who do a good job write the best code in the shortest amount of
As much as it pains me, this is an undisputed fact. If you get two developers to implement the same ticket and both hit the definition of done, but while one takes an afternoon the other takes two weeks, who performed better? That's the reality of today's corporate software dev culture. The best code possible is that which meets the definition of done and is delivered in the shortest amount of time and preferably requiring the minimum amount of changes possible.
> - more time always leads to worse code (unnecessary abstractions, handling non-existent requirements)
No, that's not a function of time. The problem I stated is that in today's corporate software dev culture goldplating and over-engineering are code smells. Thus the pressure is placed on adding code that is less robust and adaptable to change. Consequently, technical debt piles up whenever new requirements emerge because the current culture puts a pressure on "good enough, delivered as fast as possible". Refactoring and redesigning and cleaning up are deemed unproductive tasks that deliver no improvements or new features, and whoever delivers more features is deemed a more productive developer. Hence, today's software development practices favours accretion which results in continuously growing technical debt.
Debt may not be an overwhelming problem in itself until misfortune creates issues which would not be overwhelming otherwise, usually in financial terms.
A small technical upset or failure can aggravate larger technical debt, not unlike a small financial upset or failure can amplify the threat of outstanding obligations.
Only the latter is usually visible and numerically measurable in any way.
In its ultimate form, technical debt is the liability that can cause bankruptcy of a technical company without ever showing up on the bottom line.
To put things on a level playing field and really bring it home, I agree with comparing your own solution after a rushed 2 days versus a full two-week completion of optimized code addressing the same issue.
>today's corporate software dev culture
Doesn't sound like it's good enough for NASA, but then again NASA doesn't have to worry about bankruptcy.
The shortest time possible to reach the moon was not accomplished using software taking the shortest amount of time to write & test to no end.
Google's tops in search now because of code they started on 20 years ago without ever giving up.
Not on what they accomplished last year, and especially not a 2-day sprint whether it has been deployed or not.
Technical debt does not have to reach its ultimate bankrupt conclusion for it to seriously dim your overall prospects.
all things being equal, shipping a feature with a 2 weeks delay is certainly bad, but often all things are not equal: the slower dev does something more and the does something less (I'm ignoring the case where the slower dev just slacks off).
The faster dev may have skipped important things, things that can potentially sink the company, like security aspects.
The faster dev may have been aware of that and still decided it was worth to complete the task even if the system as a whole wouldn't be ready to production. For example so that the feature can be seen in action in an environment where for example security is not perceived as to be a severe risk factor.
By doing so, the developer plays with the definition of done, in a way that can be either advantageous or disastrous, depending on what happens down the line. Will product management understand that the system indeed still needs more work before shipping it to a wide audience?
This is where the debt metaphor has its teeth. It allows to negotiate these tradeoffs, also across the engineering team boundaries.
You made a good argument that generalizing is an investment that often doesn't pay off.
That's a separate issue from technical debt because whether code is generalized is only one aspect of many that determines whether the code is a dream or a nightmare to work with.
For example, if all your variable and function names are vague and misleading because you didn't take the time to choose names that make any sense, that saved you time now and will cost you later, but it has nothing to do with generalization.
> That's a separate issue from technical debt because whether code is generalized is only one aspect of many that determines whether the code is a dream or a nightmare to work with.
That's one of the problems attributed to goldplating and over-engineering solutions. One man's future-proof implementation is another man's unnecessary indirection that's a problem to maintain. Thus we end up creating an environment where rigid implementations that are prone to colossal amounts of technical debt are preferred over adaptable solutions that minimize or eliminate technical debt.
This is the wrong way to describe and explain technical debt. It fails primarily to sell the wrong idea that technical debt results from incompetence or failure to do a good job.
The truth if the matter is that in software development the absolute best solution to a problem is to provide an implementation that meets current requirements and is implemented as fast as possible. Overgeneralizing is bad code. Abstracting implementation details is a code smell. Proposing an implementation that considers additional design requirements and constraints is goldplating a solution, thus the sign of a mix of incompetence and wasted effort.
But then what if requirements change? Ah, the delta between the fast and good solution for the initial problem and adapting it with quick fixes to address the new requirements is precisely where technical debt pops up.