I apologize for such a long letter — I didn’t have time to write a short one.
Most of us have a mental model of software development that goes something like this:
- Product Management collects feature requests and their requirements into a backlog, prioritizing the most important features for the business
- Software Developers process the backlog, writing code to add those features
- Ideally, there’s some architecture, testing, and project management helping improve the process and outcomes
- The application gets better because those features have been added
- Rinse and repeat
The problem with that mental model is that it is additive. Sometimes, the most important thing to do today is to take away what was once the most important thing to add.
This is definitely non-intuitive. If the backlog is properly prioritized, the features added in the past were the most important ones for the business at the time.
That the world is not static is one of the reasons that contributed to the shift from waterfall to agile development. This is true for the development lifetime; It is also true for the product lifetime.
The product should always be considered as a whole. How can you improve what you have? Is it to add that fancy new feature? Or to remove a rusty old one?
+ > - ?
Research from UVa backs up what you may intuitively think: by default, people solve problems through addition rather than subtraction. And in software development, we are definitely people solving problems.
Subtractive solutions can be better than additive ones. More is not always better. And the good news is that it often doesn’t take much to get us out of the additive cognitive short-cut.
⇧Code ⇨ ⇩Productivity
When you stop and think about it, the negative ramifications of more code expose themselves pretty readily. Typically, the bigger a code base is, the more effort it takes to evolve it.
⇧Code ⇨ ⇧Bugs
If you’re on a team that produces provably correct code, you can skip this section. For the rest of us, we know that most of the code we write is mostly correct most of the time. But whether it’s a simple logic error, failure to anticipate ranges of input, boundary conditions, or just misunderstanding a nuance of the requested feature, the code we write contains errors. Therefore, the more code we have written, the more errors there are. Finding and fixing errors can be costly, even beyond the cost the errors themselves have in a production environment.
⇧Code ⇨ ⇧Complexity
The larger software is, the more complex it typically is. This complexity makes all subsequent work slower. The cartoon about why you shouldn’t interrupt a programmer is a perfect illustration of this effect. Clean Code (affiliate link) author Robert C. Martin claims “Indeed, the ratio of time spent reading versus writing is well over 10 to 1.” The more code there is, the more you have to read and keep in mind when adding or changing code.
⇧Code ⇨ ⇧Work
Code isn’t just work for developers. Whether separate functions or not, each feature requires some form of Quality Assurance, Documentation, Customer Support, Training, Marketing. And not just for new features, but the ongoing support of existing features.
⇧Code ⇨ ⇩Security
The more code you have, the greater your application’s attack surface. It’s reasonable to assume that more code means more library dependencies, which can end up meaning a LOT more code. Given that the software supply chain has been the source of high-profile breaches recently, it’s hard to overstate this point.
Prepare for takeoff
The mental model I like to use for this is that of an airplane wing. When planes take off, they extend their flaps to effectively increase the size of the wing. This produces more lift, which is the whole point, and it also produces more drag. This is fine for takeoff (and landing) but is bad for the cruising part of the flight. Like an airplane wing, a larger code base may have more features (lift) but it also has all of the problems above (drag).
To keep your wing software as efficient as possible for flight production, here are some things to consider adopting:
Focus on Outcomes Over Output
While there are few corporate environments that provide incentives for the number of lines of code, it’s still easily measured and therefore a frequent substitute for productivity. Unfortunately, it’s a destructive one. Instead, measure the intended outcome of the system being improved. Was there an increase in customer satisfaction? A decrease in time it took to complete a task? How has the work you’re doing improved the business process you set out to effect?
Add utilization analytics
Do you know what parts of your product are being used? Web log analysis is old hat at this point. There are many sophisticated tools for understanding just how far down a page a user scrolled, or how much of a video was watched. Apply the same rigor to understanding the utilization of your application.
Introduce Subtraction Reminders
The research indicates that it doesn’t take a lot to get us over our additive bias. We just need to not be distracted, and be reminded of the viability of subtraction. Consider adding the question, “What could we remove?” as part of your sprint planning or backlog grooming sessions making use of the utilization analytics to inform those discussions.
The more you can make it part of your organizational culture, the more success you will have with it. Removing lines of code isn’t always better than adding them, but it often helps you build a better product.
So, KISS your code! Keep It Simple, Sunshine!🌞
P.S. If you’re an outstanding product manager, interested in a holistic product approach in a demanding, growth environment, let’s talk. Pearl is hiring.