Let's not call it "tech debt," it's just "mess"
Let’s not call it “tech debt,” it’s just “mess”
别再叫它“技术债”了,那其实就是“一团糟”
A few months ago I wrote about one of my methods for dealing with “technical debt” and I had to cut a huge throat-clearing section from the opening about how I don’t really like the term “tech debt” as a metaphor. Obviously I’ll use the term it when I’m talking to other software developers, but I try to avoid it when I’m talking to people in “the business.” It’s useful when it’s used correctly, but usually when software developers say “tech debt,” what they really mean is something more like “mess.” This is a common enough usage that even when “tech debt” would be appropriate, people who aren’t software developers but work with software developers often hear “mess,” and they’ll start to develop the impression that “tech debt” is something that developers say when they did their job poorly, or don’t like how the previous team did it.
几个月前,我写了一篇关于处理“技术债”的方法论文章。在开头,我不得不删掉一大段铺垫,因为我其实并不喜欢用“技术债”这个比喻。当然,在和其他软件开发者交流时,我还是会用这个词,但在与“业务方”沟通时,我会尽量避免。如果使用得当,这个词确实有用,但通常当开发者说“技术债”时,他们真正想表达的其实是“一团糟”。这种用法非常普遍,以至于即便在真正适合使用“技术债”的场合,那些非技术背景的同事往往也会将其理解为“烂摊子”。久而久之,他们会产生一种印象:所谓“技术债”,不过是开发者在工作没做好,或者不喜欢前任团队做法时找的借口。
The problem with “tech debt” as a metaphor is that businesses like debt. There’s such a thing as “the right amount” of debt for a business. It’s not zero. When you don’t take on enough debt, you’re either too reliant on more expensive forms of capital like equity, or you’re not growing as fast as you could have. You’re leaving too much money in the future, where it’s useless to you.
“技术债”这个比喻的问题在于,企业其实是喜欢债务的。对于企业来说,存在一种“适度”的债务,而不是零负债。如果你背负的债务太少,要么意味着你过度依赖股权融资等成本更高的资本形式,要么意味着你的增长速度没能达到最优。你把太多的资金留在了未来,而那对现在的你毫无用处。
Financial debt is predictable. When you take some on you know exactly how much you’ve taken and how much it’s going to cost you. You have a little piece of paper with all the terms written on it. You don’t accidentally take on debt. It doesn’t suddenly become more expensive than you thought it was going to be because you haven’t taken on that kind of debt before.
金融债务是可预测的。当你借债时,你清楚地知道借了多少、成本是多少。你有一份写明所有条款的合同。你不会“意外地”背上债务,也不会因为你以前没借过这种债,它就突然变得比你预想的更昂贵。
Some of what people talk about when they talk about technical debt meets this criteria. For example: When I initially wrote most of the SQL queries for StoryTime, I didn’t think very much about performance. I organized the queries based on what made the code easy to read, and ended up mostly mapping a single query to a single assign. I knew at the time that at some point, when there were even more queries and more people using the application, I would eventually need to go back and condense those operations to reduce the number of distinct database calls in order to improve page load performance. I took a “loan” from the future to make developer a little easier in the future.
人们口中的“技术债”中,有一部分确实符合这个标准。例如:我最初为 StoryTime 编写大部分 SQL 查询时,并没有过多考虑性能。我根据代码的可读性来组织查询,最终大多是一对一的映射。当时我就知道,当查询量增加、用户增多时,我迟早需要回头精简这些操作,减少数据库调用次数以提升页面加载速度。我从未来“借”了一笔债,为了让当时的开发工作轻松一点。
Most of what people call “technical debt” doesn’t even speed up development. Some of it is just sloppy or unskilled work. Arguably even my example above meets this criteria: This is the first time I’ve built a project with this framework that deals with this much SQL. The second or third time I build an application of this type, I might just build it with a single query that fetches everything the page needs from the beginning.
然而,人们口中所谓的“技术债”,大部分甚至根本没有加快开发速度。其中一些纯粹是草率或技术不精导致的。甚至我上面的例子也可以说是这种情况:这是我第一次用这个框架处理如此大规模的 SQL。如果让我第二次或第三次构建同类应用,我可能一开始就会用一个查询把页面所需的所有数据都取出来。
The classic example of “that’s not technical debt, that’s just mess” is slow, unreliable, or insufficient tests. If you’re good at writing tests it’s not actually any harder to write tested code than untested code, and the benefits to project velocity accrue immediately. Writing fast tests and reliable tests are also strictly a matter of craft. If you know the techniques for making tests fast and reliable then it’s easy to write fast and reliable tests. It’s not “debt” to not know how to do something.
“那不是技术债,那只是烂摊子”的经典例子就是:缓慢、不可靠或不充分的测试。如果你擅长写测试,编写有测试的代码其实并不比没测试的代码更难,而且它对项目进度带来的收益是立竿见影的。编写快速且可靠的测试纯粹是技术活。如果你掌握了让测试变得快速可靠的技巧,那么写出这样的测试就很简单。不知道怎么做某事,这不叫“债务”。
Other times people say “debt” to mean “this isn’t to my taste.” I’ve known teams that decided their proliferation of container images was “technical debt” and spent a few weeks consolidating them into one image. Then a year later and with some new personnel on the team, they decided that having a single container image for everything was “debt” and broke it up into a bunch of focused images.
还有些时候,人们说“债务”其实是指“这不合我的口味”。我见过一些团队,他们认为容器镜像泛滥是“技术债”,于是花了几个星期把它们合并成一个镜像。一年后,随着团队加入了一些新成员,他们又觉得把所有东西塞进一个镜像里是“债务”,于是又把它拆分成了一堆功能单一的镜像。
I’m not against aesthetic judgements. They’re underrated in our field. I don’t even think either version of that team necessarily did the wrong thing. But “this work is organized in a certain way that has tradeoffs I don’t like,” isn’t “debt.”
我并不反对审美判断。在我们的领域,审美判断被低估了。我甚至不认为那个团队的任何一个版本做错了。但是,“这种工作组织方式存在我不喜欢的权衡”,这并不叫“债务”。
My biggest problem with the metaphor, though, is the cost predictability part. “Debt” implies that the cost of the decision can be understood at the time this is made. In my experience this is very rare with technical decisions. The vast majority of what I’ve seen called “technical debt” was not well understood when the team first made the decision to take it on. Usually at the time it seemed like a minor efficiency, or even “doing things the right way.” Only later did they discover that the choice had some kind of explosive property.
不过,我对这个比喻最大的不满在于“成本可预测性”。“债务”暗示着决策的成本在做出决定时是可以被理解的。但在我的经验中,技术决策很少能做到这一点。我所见过的绝大多数被称为“技术债”的东西,在团队最初做出决定时,根本没有被充分理解。通常在当时,那看起来只是一种微小的效率提升,甚至是“正确的做法”。直到后来,他们才发现当初的选择具有某种“爆炸性”的后果。
For example: I’ve done a lot of consulting on systems that were event-driven using AWS Lambda. Typically the team that builds these systems would have a lot of experience with doing something similar with a monolithic, request-driven architecture, and a lot of experience with painful scaling problems. They’ve read about event-driven systems and they’ve decided they would have much better scaling properties than the request-driven system they built the first time. So when they get a second chance, they go all-in on events. I usually come in at the point where no one understands how the event-driven system works, because it turns out it’s very difficult to trace a particular customer action through to the part of the system that’s failing in a system like this, and because no one had ever built a system like this before they didn’t know how to instrument it correctly to deal with that problem. Oh, and, by the way, the system handles about half an event per second.
例如:我曾为许多使用 AWS Lambda 的事件驱动系统提供咨询。通常,构建这些系统的团队在单体、请求驱动架构方面经验丰富,也深知扩展性问题的痛苦。他们读过关于事件驱动系统的文章,认为这比他们第一次构建的请求驱动系统具有更好的扩展性。因此,当他们有第二次机会时,便全盘转向了事件驱动。我通常是在没人搞得懂系统如何运作时介入的——因为在这种系统中,追踪某个特定客户操作在哪个环节失败非常困难,而且由于没人以前构建过这种系统,他们根本不知道如何正确地进行埋点监控。哦,顺便提一下,这个系统每秒大约只能处理半个事件。
That’s not technical debt. That’s buying private credit because your financial advisor recommended it, only to realize later that you can’t take your money back out for thirty years.
那不是技术债。那就像是因为理财顾问的推荐而购买了私募信贷,结果后来才发现这笔钱三十年内都取不出来。
The problem with saying “technical debt” in these situations is it makes you look unserious. If you use “technical debt” to mean “a problem we didn’t realize would be there when we made this decision” it makes you look like you take on debt without reading term sheets. Maybe in a better world software developers would always know what the costs are of the decisions we’re making at the time that we make them, but that’s not the way the industry is.
在这些情况下使用“技术债”这个词,会让你显得很不专业。如果你用“技术债”来指代“我们在做决定时没预料到的问题”,那看起来就像是你连条款都没读就背上了债务。也许在一个更理想的世界里,软件开发者在做决策时总能预知其成本,但现实并非如此。