The Three Values of Software
Soon after adopting a lean/agile mindset, companies often struggle with the notion of business value. Most notably, each of us appears to have his own idea what business value means, although I think it more likely that each of us simply chooses a different aspect of business value to represent most strongly. Groups working together generally benefit tremendously from this variation in opinion, but each disagreement on its own can appear to threaten the group’s ability to work as a team. Given the central role that business value plays in the lean/agile approach to delivering software, these groups need some way to turn their varied perspectives on business value from a distraction to a source of strength. I use a simple model that I have adapted from my work with ObjectMentor, which I’d like to share with you now. It describes three values of software: features, design, and feedback.
The First Value: Features
When we use the term business value, we usually refer to the most evident source of value in software: the money we get when we sell those features to paying customers. Most groups understand this value of software quite well, it engenders precious little controversy, and we can often measure it clearly and objectively. These groups still have to work hard to decide how much money to charge for their features, and we have the open question of how to measure the monetary value of individual features, but I think we can safely agree about both the existence and importance of the raw sales value of features. I find that clear and significant enough to call the sale value of features the first value of software.
The Second Value: Design
Programmers want to refactor; business people want to add features; this conflict results in a shocking amount of wasted energy on software projects. The system seems stacked against us: product directors1 should think up more features than we could ever build, and once we’ve fallen far behind schedule, we scramble to release features as soon as we can, which generally means borrowing against future effort to make things easier now. Programmer feel pressure to let the design crumble, and have no good explanation to support their position, so they give in. I have found a reasonable explanation, if not an airtight one.
I can’t quantify the value of simple design, but this diagram compares the cost of adding features over time depending on whether we choose to simplify the design or not.
When valuing expediency over the long-term view, we start by adding features quickly, but as the project progresses, the cost of adding features increases. Early on, the cost rises slowly enough for us to ignore it, but as our ideas about the design change, we add patch on top of patch, and this causes the cost of adding features to jump. The resulting cost curve looks exponential, which means that by the time we notice the cost rising sharply, it has spiraled out of control, and we reach project heat death: the point where the cost of starting over competes with the cost of continuing. You’ll know you’ve reached heat death when the company installs a new CIO, or a new lead architect, who suggests we rewrite the system in Python. We can do better.
We can keep the design simple over time, such as by following the Simple Design Dynamo, we start less quickly, but we sustain our pace better over time. The cost of adding features does rise, but very gradually, often enough that this rise in cost doesn’t affect our estimates. It becomes much more likely that we build version 10 on the same code base as version 3, as we keep the cost of changing the code base quite low. We achieve this by refactoring and writing good tests.
When programmers write focused microtests and remove duplication, they tend to write more loosely-coupled modules. Changes remain localized and have very few unexpected consequences, allowing us to add features with confidence once we learn which part of the system to change. When programmers write code that reveals its intent better, they tend to write self-documenting modules, which make it easier to know where to write code to add a given feature. Programmers keep the cost of adding features lower by knowing which part of the system to change and changing it correctly with confidence, all by following the Simple Design Dynamo.
While this diagram has the same shape as the preceding one, it shows something slightly different. In addition to keeping the cost of adding features generally low, caring for the system’s design also helps a feature retain its option value over time. By this I mean that the cost of adding a given feature rises only nominally, rather than exponentially, the longer we wait to implement it. Refactoring and following the four elements of simple design allows business people tremendous flexibility in choosing the sequence of implementing features without having to worry about the cost of delaying feature X in order to deliver feature Y now.
You might already see how this follows from the cost curve of adding features in general: if we can keep the cost of adding features from rising sharply, then we can delay adding feature X knowing that the cost to deliver it 3 months from now will only be a bit higher than delivering it now. Deferring commitment to individual features provides an essential benefit of the lean/agile approach, namely the ability to seize fluctations in market conditions or changes in the needs of the business to change the project’s focus. By keeping the design simple, we don’t lock the business in to a particular plan. Moreover, by deferring commitment, we allow ourselves to defer decisions while we gather more information with which to make better decisions, which lies at the center of real options thinking, a significant advancement in lean product development.
Even among those who generally agree on the value of simple design, I have seen a spectrum emerge, and I’ve placed Bob Martin at one end and Josh Kerievsky at the other as avatars for the seemingly-divergent points of view. Uncle Bob, Corey Haines, and members of the software craftsmanship movement generally advocate for clean, almost antiseptic, code. Josh Kerievsky, Naresh Jain, and Jason Gorman generally advocate for a much more just-in-time approach to clean code. Each group understands the value of a simple design, but quantifies that value differently. I tend to teach the “uniformly clean code” approach to groups starting out with designs that require considerable cleanup, because they have no useful baseline for quantifying the value of simple design for their particular software income stream. As they improve at gathering evidence to support a specific valuation of their design, I advise them to move in the direction of a more just-in-time approach. Sadly, employing a just-in-time approach to cleaning up the average software design tends to equate to doing what they’ve been doing to this point: procrastinating on sorely-needed refactoring. They already know how to do that, so I don’t need to teach them any more about that.
I believe that I have provided several reasons to incorporate the value of simple design in our conception of business value—enough to justify calling it the second value of software.
The Third Value: Feedback
You’ll find the third, and perhaps least generally defended value of software, in the feedback groups receive by placing an early version of the software in the hands of real customers and real users. We want people to say “That’s not what I meant!” as soon as we can, because then we have more time to change what they don’t like. Feedback plays such a central role in the lean/agile approach to delivering software that Extreme Programming includes it as one of its key values, along with respect, courage, communication and simplicity.
You have probably experienced the typical weakness of long projects: after working for six months to two years, you present your final product to the market, and at best they complain that your software doesn’t really solve their problems, and at worst, they merely yawn. All other things equal, delivering the first half of a product before the second half gives your customers and your users the opportunity to tell you when you’ve veered off course sooner, so that you have fewer features to throw away, less code to change, and more time to do it. Even more significant, you might find that your half-completed system satisfies more than enough of your customers’ needs that they’d happily pay you now for the work already done. You might even have the opportunity to stop work on this project and turn your attention to other, newer potential streams of income.
Now imagine the possibilities if you delivered the first quarter of your product, or the first 15%. The sooner your customers can tell you something about the system you’ve built, the sooner you can either correct poor decisions or simply notice that you’ve hit the elbow of the curve of diminishing returns. You can achieve this by delivering smaller, less complicated features; by taking a breadth-first, rather than a depth-first approach to delivering a cohesive system; by employing techniques like dimensional planning2 to avoid committing too early to feature enhancements. These techniques all belong to the approach I call Value-Driven Product Development, an element of the way I practise and teach behavior-driven development. I find this more that significant enough to call it the third value of software.
In this article I have described three important aspects of business value: the sale value of features themselves, the marginal cost of and option value of features through simple design, and the avoidance of sunk cost from delivering the wrong features and opportunity cost from delivering too much of the right features. Rather than try to balance these as competing interests, I encourage you to see them as complementary parts of a cohesive approach to maximizing business value. We have to do more than simply write good stories and cajole programmers and testers into building them as quickly as they can. We benefit the most when we write good stories, refactor mindfully and fastidiously, and ask for frequent feedback from real customers and users. We need to do more than that, but at the very least we need to do all these things in order to stand a strong chance of delivering a strong product that sells well and continues to satisfy our customers over time.
J. B. Rainsberger, “Putting An Age-Old Battle To Rest”. A description of the Simple Design Dynamo, which has its roots in the four elements of simple design.
The people responsible for the final decision of what to build in which sequence. I prefer this term to “product owner”, which feels more controling and less open to working together.↩︎
An approach to slicing features that has a strange name. It guides practitioners to think about how “polished” a solution they really need to a given problem, resulting in investing just enough in a feature to get the desired value.↩︎