7 ms·
Technical Debt 101
- the_watcher 12y agoI like the concept of Minimum Lovable Product, although MLP isn't as catchy as MVP (thanks to sports). It's probably good to think of an MVP as a step on the way to an MLP - the MVP is the one you release to specific audiences of likely users or show to angels or seed investors to show that it can work, and be very explicit about it not even being a beta version - more like a version 0.1.
- dllthomas 12y agoI don't understand why bad code is "not technical debt". It seems to me technical debt, poorly spent. Someone who takes a payday loan to buy beer is still incurring a debt. If there is some more meaningful distinction here that I'm missing, can someone clarify?
- polemic 12y agoThat was my thought too. I guess OP was trying to distinguish between debt deliberately incurred vs wasted. But maybe a better way to think about it is "leverage" vs "debt". Leverage is something you use to improve the product with a known and (hopefully) quantifiable return, whereas plain old debt represents those poor non-decisions.
- diggan 12y agoIf the bad code is still tested, it can easily be changed to be "good code". If you have good code, but untested, you have no way of refactoring the code without actually knowing that you making it better.
- sheepmullet 12y agoBad code with unit tests cannot easily be changed to "good code". Most unit tests of bad code are very brittle. Consider changing the permissions system in the article: All a typical rushed set of unit tests would do in this case is form a brittle specification. In fact in my career I've never seen bad code + good tests unless the tests were added at a later date (typically by another developer trying to do what they can to stop code rot). On the other hand it is a joy and straightforward to add unit tests to good code and typically they are much less brittle.
- michaelfeathers 12y ago'Technical Debt' is a case where a specific thing was named before the general concept. Another case is the phrase 'mock object'. In the early 2000s, the original mock objects paper coined the term and defined them as testing stubs with builtin expectations. For years, people used the term "mock object" for any sort of stub. Technical Debt is a very specific metaphor that Ward Cunningham framed as a strategy. Ever since, though, people have used the phrase for all sorts of entropy in software. If you look around the literature, you'll see people talking about type 1 and type 2 technical debt. In my experience (and I'm the guy who wrote the Legacy Code book mentioned in the article), the typical entropy thing that we see in software has more to do with just taking the easy way and avoiding refactoring - different from Ward's concept.
- deleted 12y ago[deleted]
- patja 12y agoAlways an interesting subject. I can't help but feel it would reach a much wider audience and achieve a greater impact if it was subjected to an automated grammar check, or edited by a native English speaker. I could not get through all of the distracting grammar errors, and I suspect most non-technical English speaking managers (who seem to be the intended audience?) would have the same reaction.
- Domenic_S 12y agoHmm, I didn't notice any.
- LyndsySimon 12y agoCould you provide some examples? As a native English speaker and someone who prides themselves on their ability to clearly convey complex ideas through prose, I don't recall a point where a grammatical error detracted from my understanding.
- Joeri 12y agoI've had occasion to think a lot about the relationship of quality to long term productivity. The remarkable thing about building software quickly is that if you focus on speed, cutting quality where needed to "move forward", you end up slowing down after a while, due to the build-up of technical debt. A continued focus on speed will typically result in slower development, and a low-quality product, a sort of worst of both worlds scenario. On the other hand, if you focus on quality, you end up making choices that enable fast development. You make sure you have high-quality requirements and a deep business domain insight in the whole team, which means you end up writing only that code which you truly need, and write it in the right order (most important features first). You make sure you have code that is well-covered by tests, which as a happy side-effect makes it easy to adapt to new requirements. You focus on having a high-quality deployment process, so the amount of customer issues that result from a broken deployment go down reducing the load on your dev and support teams. Focusing on quality first is not about gold-plating code, it's about making conscious decisions to have a high-quality process from front to back, and those decisions typically result in a highly efficient organization. It's no accident that those teams which manage to ship releases every few weeks (e.g. firefox, chrome, facebook) have world-class products. You have to focus on quality to go fast. This isn't just theory. Capers Jones actually measured this. The fastest delivery schedules were produced by teams with the highest quality product. http://www.parasoft.com/products/article.jsp?articleId=2769 http://www.parasoft.com/products/article.jsp?articleId=2769
- mattgreenrocks 12y agoThis has been my experience as well. There is only one speed, and that is doing things well. I'm convinced a lot of developers have been completely brainwashed by the Business in believing they don't need to ship good code. They absolutely do, and the cost of it is high. The cost of maintaining bad code is much, much higher, however. Abdicating this responsibility reflects poorly on you, the developer. Much of the populism in software targets the insecurity of those who don't push themselves to ship great code: "getting things right is so hard! Just do the best you can and don't sweat those edge cases too much!" I sweat the edge cases when I'm writing the code in the first place because I'm incredibly lazy: I know the mental cost of re-creating all the context necessary to solve the problem later is very high, and I'd rather not return to the feature ever again.
- rhspeer 12y agoWhile a good post, the real issue is that non technical managers of technical projects is quickly becoming more of a risk than many projects can prudently accept. The old, and unfair, characterization of programmers as smelly trolls that can't handle client interactions is more of a crutch for fools than a reality. The truth is my clients complain bitterly about how they'd prefer to just talk directly to the dev's and not be bothered by the various hand waivers trying to justify their line item on an invoice. Often this is a great way to annoy the dev team, but it's a good expression of the perceived value of a non technical intermediary. In the end the old truism of "You can't manage what you don't understand" still applies to this new fangled industry of software development. That being said, ramping dev's up on management techniques is another challenge, for another internet rant.
- alphanumeric0 12y agoCan I upvote this like a million times?
- templeos2 12y ago"opinions are like assholes, everyone's got one." You bore me.
- jasode 12y ago>Thousands of startups have launched and failed precisely for the lack of quality. That was an emphatic statement in the article and I feel the discussion would really be constructive if the author (or posters in this thread) listed concrete examples of startups that failed primarily because of software quality. If success has many fathers, failures are not orphans and also have many fathers as well. Perhaps software quality was not the 1st but actually the 2nd or 3rd reason why the company failed. I'm not saying such examples of software execution killing the company don't exist. I just can't think of any prominent examples at the moment. I'm leaving out poor software examples such as the Atari 2600 E.T Extra Terrestrial game cartridge because that was not a startup situation.[1] [1]http://en.wikipedia.org/wiki/E.T._the_Extra-Terrestrial_(video_game)#Critical_response http://en.wikipedia.org/wiki/E.T._the_Extra-Terrestrial_(vid... On the other hand, an internet company like Friendster looks like an interesting case study. Their infrastructure software was not efficiently traversing their social graph. It was something Facebook programmers conquered but Friendster did not. But was software quality the #1 reason behind Friendster's demise? Apparently, the board-of-directors didn't prioritize and throw money at the engineering challenges that Friendster was facing.[2] So the their failure can be reinterpreted as a combination of management of priorities and software execution. Maybe if they did throw money at the issue, it wouldn't have mattered because their programming staff didn't have the unique competencies to tackle at-scale social graph problems. In that case, it's not a "technical debt" issue but a "hiring talent" issue. [2]http://highscalability.com/friendster-lost-lead-because-failure-scale http://highscalability.com/friendster-lost-lead-because-fail... Another case study might be the Chandler software (chronicled in the book "Dreaming in Code"). However, it appears that the product got bogged down by architecture astronauts unable to make decisions and not "technical debt". If there are thousands of companies that failed on software quality, it'd be interesting to see which ones can be disentangled from non-software issues and we can confidently say, "yep, that technical debt is what killed them." (My curiosity for real examples does not mean I'm endorsing technical debt. I'd just like to get some real-world perspective on this topic.)
- slightlycuban 12y agoI'm not really a fan of the story-point example. The article begins with: > it’s something that you get when you delay design decisions for later But then presents us with a problem where we can "spend" 21 story points now, knowing we won't have to do much refactoring later. How do we know this? I thought the whole point was we couldn't see enough of the picture to make a stable design. Instead of talking about how patches, hacks, and workarounds impact code, I'd like to see discussion on how you move forward when you know the requirements are going to change, but don't know how.
- sheepmullet 12y ago"I thought the whole point was we couldn't see enough of the picture to make a stable design." While still technical debt it is not the type the article is talking about or using in the example. FTA: "At this point the developers realize that the code is starting to get messy and the solution is refactoring it to have a decent permission system." I.e. You are at the point where you realise you need a better design and know the rough solution. Do you keep putting band aids on your solution or do you properly refactor?
- sheepmullet 12y ago"I'd like to see discussion on how you move forward when you know the requirements are going to change, but don't know how" I've found requirements do not change nearly as often as you would think. Only maybe 10% of the changes I make come from a requirements change. Take for instance the articles permissions example. Is that a change in requirements or a lack of understanding the requirements and domain? Sometimes it is a genuine requirements change. Maybe the company has recently adopted a new security policy, or maybe you are selling to a new customer and they require permissions even though none of your existing customers do etc. More often than not though the requirement has always existed but the dev team didn't know about it or didn't have time to deal with it.
- slightlycuban 12y agoIn my line of work, either I'm building a new component, or I'm dealing with requirements change. So dealing with the shifting sands of what the system should do is a major concern. Requirements come and go for me. And losing requirements can be just as disruptive as getting them. Worried about how component X will handle users? Well, we don't ship component X anymore, so any refactoring work you've done is wasted. I might be the odd one out with requirements changing all the time, but I don't get the choice between good design and fast design. I have to creep forward in my architecture, like I'm fumbling around in the dark, because what my system should do today may not hold until tomorrow.
- jackgavigan 12y agoIt's possible to minimise the technical debt you take on (without spending the full amount up front) by being smart about your application's design/architecture. Using the user roles example given in the article, it's not beyond the wit of man to foresee that you're going to need user roles at some point in the future, so you can make provisions for adding it in later. Done right, the extra effort is minimal but means that you'll be able to plug in the new functionality at a later date without needing to refactor the entire codebase. It might be as simple as figuring out where the permissions/role check will go and including a "# Future permissions check will go here" comment. Or you might actually include a check that calls a dummy service/function which always responds to a "Can this $user do $action to $resource?" query with "Yes". Then, in a few months, you can simply replace the dummy service/function with a real one. You don't even have to design/architect the whole thing up front. You just need to avoid painting yourself into a corner. Ask yourself "What am I likely to need in the future and can I do something cheap now that will save me a lot of time/effort further down the line?" If you ever need to explain this concept to a non-technical manager, tell them that it's like applying a kind of net present value calculation to development time/resources: Spending a little extra now means you can potentially save a lot further down the line.
- ch4s3 12y agoExactly. I really like writing future focused interfaces like that. They're light weight, and can save a lot of time later. It's like building good credit to get a lower interest rate on your technical debt.
- rdtsc 12y ago> It might be as simple as figuring out where the permissions/role check will go and including a "# Future permissions check will go here" comment. Very good point. I was thinking about this issue not too long ago. And the ability to do that, comes with experience and often separates normal programmers from much better programmers. It also takes a while to detect this, because there needs to be enough "Futures" that become present to tell if the original architect predicted or foresaw or did they just over-abstract or and overloaded the code with potential apis or features. More often than not I see the later. "This code never runs","why is this here","we have 4 levels of abstraction for this, why?". "Oh because I thought we'd have this and that in the future so I added in". Quite rarely I see the former. When a developer is asked "can we add this?" they come back and say "yes easily, I knew you'd come and ask for this so I added the abstraction to handle it or add stuff to it later". The one thing I noticed is that this becomes a pattern for people. Some people create the former type software some the later.
- leoc 12y agoI don't see why the analogy to debt is necessary when the direct analogy is to capital underinvestment: in fact what we're talking about is or very nearly is just that, capital underinvestment, not simply something analogous to it. And the hypothetical businessy, non-technical types whom the debt analogy is intended to enlighten understand very clearly what deferring capital investment is and what the likely consequences are, at least if they actually know anything much about business.
- msandford 12y agoMost of the people who are pushing for "features now, someone else's problem later" are probably not upper management but rather middle management. Upper management might understand capital underinvestment. Capital underinvestment is very nearly the sole job middle management is there for. And berating people for not being done yet. At least at a couple of the places I've worked.
- personZ 12y ago"Bad code" is a completely subjective measure which everyone is sure they will know when they see it, but few agree on the actual definition. Extreme examples will be floated, but in practice what people consider "bad code" are things that made decisions that aren't sustainable. For instance a complete lack of permissions. A lack of logging. A lack of multithreading if it's a CPU bound process. Locks. Dependencies. Etc. Each person and team really does define bad code differently, and often in complete contrast with each other. There are people who considered DI heavy code bad code. Heavily abstracted and layered Java code is considered great code by some, horrendous code by others. And on and on.
- joseph4521 12y agoTo me, all code is debt so long as it requires maintenance. It will be read and modified hundred of times after being initially written hence why you want to have as few as possible. Code also need to be hosted on servers somewhere and that's a sort of debt too since you now are forced to maintain the infrastructure, keep the software updated, ensure it's always running. However, you have to accept a certain amount of debt otherwise you will never be able to launch anything. Everytime you can invest some time to reduce maintenance later down the road, it's like getting a lower rate on your debt. However no matter how hard you'll try, if the project is used it'll require love, time and hard work to keep it going. Then comes a time where either the project fails and you take it down (and stop paying any debt) or, if you're lucky, the balance between ongoing cost and benefits start to even out and you're finally out of the woods.
- jameshart 12y agoThis isn't a 'primer' about Technical debt - it's an opinionated piece about the value of the concept of technical debt, which I think is at least a 102 or possibly 201 level course on the subject, and needs to be taken in the context of other material. I suspect it hasn't been tested out on many nontechnical managers, either - using the concept of electron spin (for a nontechnical audience, remember) as an analogy for the concept of analogies is the kind of meta-analysis that I think will lose them pretty early on. I think the real problem of this piece is that it flatters nontechnical managers, as businesspeople, by describing technical debt as a sensible business decision they can get into consciously through clearheaded negotiation with their technical team; then characterizes 'bad code' as something different, that happens when the technical team just don't do their job. This alleviates the nontechnical manager of any responsibility for bad code. The fact is that knowing about technical debt is not necessary to find yourself up to your neck in it. A team which goes for years taking shortcuts, being forced to hit unrealistic deadlines, or which lacks the skills to really build a good, robust system, is like a kid with a credit card who doesn't get that just paying the minimum payment each month isn't going to work forever. Every shortcut they get asked to take, they swipe the card, and they get to walk out of the store with the goods, and it seems to just keep on working; thousands of dollars worth of stuff, and they just have to pay a few hundred each month. It's magic! But the consequences will show up in the end, either in the form of a long period of hard graft to pay it down, or declaring bankruptcy and abandoning the codebase. That's why I love the technical debt analogy - different people manage financial debt differently, and most businesspeople understand the concept that planned debt is necessary and beneficial for growth; arguing that Ward Cunningham and the author don't think you should call other technical debt by that name seems petty, and not particularly useful, when extending the analogy to runaway debts works so well. Overall the problem I really have with this piece is that if I tell a manager "This project is carrying a bunch of technical debt," now they'll google it, find this, and come back to me with "You mean it's a pile of bad code." Which is true, but how does that help us? When I make the argument that a troubled project needs to pay down some technical debt, I'm trying to make clear that we need to start paying off more than just the minimum payment every month. If the technical debt analogy is removed from the table, I'm left with just saying the team needs to replace the bad code with good code. And then they'll tell me that this piece also told them that the 'big rewrite' was a bad idea too... So how has this helped?
- adamconroy 12y agoI think analogies generally suck. Better to analyze things for what they are. Analogies are good for explaining difficult to understand concepts, but all to often people say, x is analogous with y, y has something good/bad about it, therefore x has something good/bad about it. Technical debt is a good example of a bad analogy : 1. Assume some piece of code works, technical debt is only an issue if that code ever needs to be modified. Financial debt is always an issue regardless of what happens, even if you die. 2. Writing some code that generates the so called technical debt will often have an upfront cost saving, so whilst it might incur some extra work down the track, the extra work isn't a straight cost. The cost = (extra work - time saved up front). 3. Attempting to avoid technical debt often ends up with over-engineered code. 4. Being dogmatic and avoiding technical debt in all projects is often not good for the project / business / investors. Being early to market at the cost of code quality is often very important. I think point 3 is the worst scourge of all. It is quite common amongst mid-range developers. After working for a while they start to get good development skills and start to think too much, looking for ways to express their skills. In summary, it is like most things in life, there is a balance to be found.
- adamconroy 12y agoSomething that gives a counter opinion to group think is never appreciated. Better we all sit around and stroke our egos, with every statement implying how magnificent we are and at the same time implying how everyone else is churning out debt filled shit.
- vpeters25 12y agoI am not sure "delaying business decisions for when you have better information" causes technical debt. Under this premise, pretty much every agile development project would be technically bankrupt.
- craigyk 12y agoI like its target audience, but am I supposed to just forward this to my superiors? Can't imagine they won't feel at least a little insulted, even if it's a concept they need to understand.
- swalsh 12y agoHere's the analogy I made up a bit ago trying to explain the concept. As programmers We build code paths. Design mazes. In the beginning the maze is simple, there's only a few paths. To make things simple we separate our ideas into many small mazes. Since they're small, it takes a short amount of time and concentration to predict the different possible paths in our heads. Technical debt is when, due to to time constraints the decision is made that it is quicker to draw one more line on an existing maze, rather than create a whole new small maze. In the beginning it seems not so bad, you can still take in the whole maze at once. But as time goes on, that one maze gets larger and larger, and finding a successful path through it takes longer, and longer. Eventually you get to the point where you can't separate the maze because too many of the paths are built on top of each other, but you also can't manage the maze because its to large itself. That's the default. That's the rewrite.