1. 29
  1.  

  2. 11

    Bookmarked this article specifically for its wonderful definition of “tech debt,”:

    Technical Debt is incurred when software or system designers take short-cuts to ship a feature faster by increasing the overall complexity of the system.

    1. 6

      I like to differentiate between suboptimal implementation and legitimate technical debt.

      Suboptimal implementation could be a naive algorithm (from a big-O) perspective that you won’t be penalized for because N is typically very small for quite awhile. It could also be a poorly factored module that talks to some service you can’t touch. The important thing here is that suboptimal implementation choices don’t constrain future choices because they’re contained. This is something you can circle back to when necessary. Not all code has to be perfect, it just has to be good enough to not be the weakest part.

      Contrast with technical debt, where the debt has a way of showing itself even when you’re trying to get away from it. It could be a magic global value that you have to carefully work around, or a lack of safe constructs to use when operating several pieces of mutable state, where you get the feeling you’re constantly juggling knives and if you don’t do it exactly right in a certain way, it will fall to pieces. This is the sort of code you try to burn with fire because it infects everything and destroys your ability to code confidently, much less reason about the code.

      I believe this additional distinction is important to make because when prioritizing work, you absolutely do not want the latter variety of technical debt because it impedes your ability to work and grow the codebase. In the case of the former, it might be some slightly embarrassing code, but it isn’t code that is hindering forward momentum. I also think it is good, as developers to be honest about the real impact of technical debt when discussing priorities with our coworkers. We can be pretty bad about making a huge deal about some minor things, (“omg bob used an old timezone JS library, what a moron!”) and utterly passive about others, (“well, I don’t really understand how payment works but I made a minor change and it seems to be okay so we’re good for now.”)

      1. 2

        The sensational title honestly makes the article sound worse than it is.

        1. 1

          Ok between this and the Ops Lessons earlier, I feel like Lobste.rs is reading my resume and messing with me.

          All of this is hugely relevant when you’re doing a legacy modernization and also still supporting the legacy system. It’s even worse on data projects where you have to deal with the persisted fallout of every single piece of technical debt at once.

          This one is getting bookmarked for future use.

          1. 1

            Technical debt is too broad of a term, and our industry should have more terms for things we would not deem “new features”.

            To me technical debt is not something where the execution and behavior of the system is equivalent in all black box observable ways, except maybe memory access patterns. That is more likely an ergonomics issue.

            • Problem 1: the system has technical debt, and has definable risk to the system soon. Heroism rarely helps, as you need to engineer your way back out of the problem. Maybe you call into external systems you have deprecated, you use an old API that you’re solely supporting now, an old database needs to be migrated to the new database, etc. These can be listed, prioritized, and generally worked on just like any feature work. If you can define the risk, you can define the expected value of the change.

            • Problem 2: the system has poor ergonomics, and has unknowable risk to future project velocity. Heroism usually helps here in the form of many refactor patches. These are usually bad class hierarchies, using libraries in weird unintended ways, lack of modularity, poor reusability in tests, etc. These are very difficult to prioritize, because defining the expected value of the change requires metrics most organizations don’t have (time to develop new feature in the area of code with the ergonomic problem).

            The solutions for each of these usually look radically different. I wish we had even more terms for each type, so software engineering could come up with general patterns in how to address each.

            1. 1

              I read somewhere that technical debt has compounding interest, I haven’t seen that mentioned here. Twice the tech debt requires much more than twice the time to make changes.