Hacker News new | ask | show | jobs
by lostcolony 4322 days ago
'Most people assume technical debt is there because of time constraints.'

As opposed to what? He describes three personality traits, only one of which (hubris; not entirely sure why that's the term used given how close it is to arrogance) actually leads to additional technical debt. Both fear, and arrogance (as he describes it) merely lead to technical debt remaining unaddressed; they don't create it in the first place.

I'd posit that technical debt gets created because of time pressure, and that it stays because of continued time pressure.

Almost the entirety of my experience with technical debt has been "Hey, this code kinda sucks" "Yep. We just haven't had time to make it better/it's never been enough of a priority to make it better". Not "Don't touch that, you might break it!" (caveat: I've run into this on long lived, gigantic defense contracts) or "No, it's good the way it's written" (never run into this). I can't even imagine a developer who is any good saying that latter one; you -always- realize ways you could have made it better after the fact.

It may instead be a manager calling the shot that refactoring isn't necessary/worth it (the arrogance he mentions), and we can debate whether it's fair for management, rather than developers, deciding when refactoring is necessary, but it's still based on time/money constraints; I've never met a manager who would say no to a refactoring attempt whose cost was nil (i.e., the dev, QA, and anyone else who'd need to be involved, offered to do it in their free time).

EDIT: And even technical debt incurred because of changing requirements comes about because we didn't take the time initially to fully understand the requirements. This isn't a bad thing, it's what agile is predicated on, that we don't need a full top to bottom understanding of the problem space to deliver something useful. But it still can be expressed as a time constraint, one on the time it would take to expand our understanding, rather than one on the time it would take to code.

2 comments

>I'd posit that technical debt gets created because of time pressure, and that it stays because of continued time pressure

I think you could boil everything down to "time pressure" and not have any good insights on a problem. For us our technical debt came in the form of resource constraints, namely not having enough money to hire someone to be able to do a task in the most optimal way. Sure we didn't have years and years to learn a new codebase but I don't consider that "time pressure" in the same sense.

I do think in general though if you are "hacking" on a product, you are almost by definition not building it in the most optimal way. In general things are left out or overly complex, whether it be documentation or streamlined code or building with a non-native SDK instead of native development technical debt sneaks in there.

Or how about developer maturity? Looking back at some of the projects I worked on when I was just starting out as a professional developer, I can tell you without a doubt that I introduced technical debt. It wasn't because of time pressures, I had plenty of time, it was simply because I was so green that I didn't know any better.

For example, I built a distributed video transcoding system a few years back, and for the use case at the time it worked great. But let's say people want a new video format? That's a large rewrite. Want to add more servers into the worker pool? That's a large rewrite (the code was written to assume a 1:1 ratio of certain servers, which was dumb).

Basically anything that you might want to change was made harder by the code that I wrote to get the job done initially. Over the years you start to recognize that, and write your code a little smarter and more change tolerant (hopefully introducing less technical debt).

Agreed, though I would distinguish tech "debt" from using your same tool to solve different problems. In general I would view tech debt as something that you know you are incurring eg. this situation: I know that this hack I am doing is going to need to be fixed later to implement Y, but since we need to implement X right now we have to just get it done
Yeah, my point wasn't that you can't drive deeper into the problem and come up with something more specific, but that the statement this article leads with (''Most people assume technical debt is there because of time constraints') is misleading. Of course people assume that, because most of the time it's true.
And with methods like TDD: "don't touch it or else you will break 1500 pointless unit tests that don't correspond to any actual functionality and will have to be rewritten". But you can, with great confidence, make changes which, so to speak, shuffle the same technical debt among different accounts.
Not specifically to TDD, but tests are one of the things that helps keep that particular complaint from being used. You -can- refactor with some assurance that you won't break anything (as the tests will either continue to pass, or they'll break, and in investigating them you will confirm that your changes broke only the things you intended to change). Without tests, refactoring becomes a "Well, we don't -think- we broke anything..."; you have no reassurance that you didn't.
Ideally tests should only test high level features and their invariants, so that a new implementation of some part should only break if the new implementation is actually broken. Unfortunately, many unit tests are written with a lot of assumptions, basically testing that you have kept the existing implementation. Especially unit tests that are written in a naive way is like this. In such a case you basically have to rewrite both the implementation _and_ all the unit tests. In that case the unit tests is in fact making change harder.

Unfortunately, much of current software development literature more or less encourage writing this kind of unit testing, in that they emphasize the importance of tests ("the definition of legacy code = no unit tests", "code without 100% test coverage is by definition low quality), while at the same time don't tell what a good unit test look like. This leads to brittle unit test suites using a lot of mocking etc, that is nearly impossible to not break if changing code at all.

Of cause good unit tests are not like this, but it means that both you and the GP can be right at times.