We (software developers) write astounding amounts of worthless software. I find it hard to fathom just how much junk we are producing. As someone who spends a fair bit deal of time thinking and writing about how to be a 10x programmer and effectiveness, I believe we have lots of room for improvement here. In this post, I’m going to examine the problem of worthless software and what you can do about it.
How much worthless software are we producing?
Tons. The Standish Group 2015 Chaos Report, concluded that only 29% of projects completed in 2015 were considered successful (on time, on budget, with a satisfactory result). 19% of projects outright failed and the rest were somewhere in between. Ouch. But project failures aren’t the only kind of worthless software.
Features users don’t use or care about
None of the Chaos Report numbers take into account all the stupid, useless, rarely used, and unused features in successful projects. (I’m looking at you, Clippy.) But seriously, look through the menus in Microsoft Word or Excel. Do you even know what half of those things do? I don’t. Can you imagine being the Microsoft developer who maintains the kerning feature in Word? It’s hard to get a good handle on the number of features that fall into this category but I feel confident saying that it is well above 25%.
Features that cost too much
And then there are the successful features within a successful project that cost way too much to deliver and maintain. I don’t have a statistic for you on these costly software engineering failures but I think we can agree this is the rule more often than the exception.
Plus, you have all kinds of code that doesn’t need to be in the project at all. I’m talking about dead code, automated tests for said dead code, duplicated code, over-engineered code, piles of code that can be replaced by one or two standard library calls, etc.
Nonviable business model
We must also count all the software produced by failed startups. The vast majority of that software dies with the startup that wrote it.
But it gets worse, so much worse
You don’t just pay for worthless software when you create it. You pay for it in each phase of the development process forever. So you might look at a feature that you wrote that turned out to be worthless and think it took 100 hours to implement, no big deal, right? Wrong.
Measuring the true cost of worthless software
If your team is like my team, you record your time spent directly building, testing, integrating, and releasing a feature but you don’t count the cost of:
- the initial discussion and investigation of the feature
- all the time you spend talking about it in meetings
- reporting on its progress
- reading the code when maintaining other parts of the system
- coupling other parts of the system to the feature (while you attempt to keep your software DRY)
- people leaving your team because your software is bloated mess and a nightmare to work on
- hiring new programmers
- bringing new programmers up to speed
- upgrading your code to deal with deprecated libraries, language features, or APIs
- keeping your code styled and formatted like the rest of your project
- tracking, isolating, and fixing defects
- extending the code
- waiting for its tests to run a thousand times a day when you are working on other features
- trying to maintain and evolve your architecture
- increasing the attack surface of your system to malicious users
- supporting the feature until the end of time (almost always happens) or porting it to the next version of the software (frequently happens) or eventually removing the feature (almost never happens)
As if all this stuff isn’t bad enough, software complexity scales non-linearly. So, after you reach a certain level of complexity, every worthless feature you add to your project makes it significantly harder to work on the rest of your software for the life of the project. Let that sink in for a minute.
And the final kick in the groin is the opportunity cost of your worthless software. What could you have done instead of pursuing and maintaining this worthless software?
So, what’s the total lifetime and opportunity cost of building, supporting, and maintaining that “100 hour” feature? Who knows–nobody keeps track. It’s almost certainly more costly than anybody would be comfortable admitting.
How to keep worthless software out of your project
I hope I’ve sufficiently scared the crap out of you. Keeping worthless software out of your projects is a major engineering challenge. Software is so easy to change compared to hardware or physical things like buildings or cars, that people find it impossible to resist the temptation to change it. So, you can’t expect your stakeholders to stop making change requests because that’s not going to happen. What you need is a system for dealing with change requests and filtering out the ones that will lead to worthless software.
This is a huge leverage point. If you can consistently filter out ideas for worthless software from your project before you build them, you are so much better off than trying to figure out how to create software more efficiently. And think about how much time you devote to that.
I don’t have a silver bullet here. But I do have some ideas for how you can keep worthless software from creeping into the various stages of your development process.
Talk to your stakeholders about the total cost of ownership of worthless software
Your first step is just to talk about the problem of worthless software and the total cost of ownership with your stakeholders. Look at your project and identify the worthless software in it. How bad is it? In which development stage did you introduce most of the worthless software in your project? To what extent is your progress on high priority features slowed down by worthless software? How much effort are you expending to maintain this software?
Can you make a business case that it would be cheaper to remove some of the worthless software from your project than it would be to continue supporting and maintaining it?
Spike and stabilize
Instead of bringing every feature to 100% production quality before you release it, in this patten you produce a sort of working prototype of a feature and get it in front of your users as fast as you can. Then you gather feedback from your real users to determine whether the feature should be killed right there or receive additional investment to make it more complete and production quality. Dan North describes spike and stabilize a million times better than I can so just checkout his talk on the subject.
Always work on the highest priority tasks
You must advocate for working on only the highest priority tasks at all times. Add your change requests to your backlog but make sure the truly important stuff is always at the top. If someone pushes something potentially worthless to the top of the backlog, don’t argue against it directly. Pick the highest priority thing in the backlog and make your case for why task B is a higher priority than task A. If that’s not enough, you can “go negative” on the task you think will lead to worthless software and make a case for why it shouldn’t be at the top of your backlog. You won’t always get your way but if you are discussing things openly and honestly, you should keep the majority of the bad ideas out of your project.
Use your lack of staff to question every requirement
Almost all software projects are understaffed or behind schedule. And if you are in this situation, you can use it to your advantage to trim the “fat”.
Just because the overall task is important, doesn’t mean that every single part of it is also important. So you need to question every requirement. It’s way too easy for anyone to write a few words into a requirements document that turns into weeks or months of work or completely thwarts your architecture.
Find the “fat” and trim it wherever you can. And if you can’t trim it, at least schedule it in the later stories. With a little luck, your stakeholders will change their minds and drop or deprioritize the stories that include the “fat” before you implement them.
This strategy also gives you time to come up with good arguments for why the “fat” shouldn’t be in the project if those stories do eventually rise to the top of your backlog.
“Fat” in this case spans all types of requirements, not just stuff your users can see. Really think about if you need to add logging and email alerts for a new feature when you’re not even sure anyone will use yet. Does it really need to be that fast at the beginning? Documentation? A full suite of automated unit tests?
We’re trying to make “question every requirement” into an official step in our development process right now because we see it as such a high leverage point.
Use vertical slicing
We often split our features into multiple stories to align more closely with our optimal pull request size. We work to implement the high uncertainty and “must have” requirements in the earlier stories and work towards the “nice to have” requirements in subsequent stories. And it’s shocking how often one of two things happens. Either we completely drop the “nice to have” stories because something more important comes up and our efforts are redirected elsewhere. Or, we learn something by deploying the early stories that radically changes how we want to approach the later stories.
Either way, it helps us avoid adding worthless software to our project. And it will work for you too.
KISS and YAGNI
KISS means “keep it simple stupid” and YAGNI means “you aren’t going to need it.” You should burn these acronyms into your brain. Every line of code you add to your project is a liability. So, if you’re adding code “just in case” or because this is where the books told you should should use the observer pattern or for any other reason other than that you need it right now, I urge you to reconsider. It’s almost always pure downside.
Similarly, you should ignore most automation, infrastructure, and scaling concerns if you’re just starting out. Address them as they become inadequate, not before.
Here are some resources you might find helpful:
- Dan North’s talk – Decisions, Decisions
- vertical story slicing
- minimally viable features
- simplicity in software design
- lean software development
Because you can add worthless software to your project any stage of the development process, you need multiple strategies to combat it. It can be difficult to maintain this level of vigilance, but the cost of supporting and maintaining worthless software is so high that you can expend significant effort up front to keep that stuff out of your project and still end up ahead.
How do you keep worthless software out of your projects? I’d love to hear your thoughts?