When we write software, a surprising amount of our time is spent not in front of a computer, but in front of our clients, educating them about the nature of software and the application development process. They’re spending a lot of money for a custom product they don’t truly understand, even if they’ve bought software before or have been in the industry a long time.
A custom software application is typically as expensive as a car or a house, but those assets are easier to understand. A house is built, you take possession after it’s finished, and then you put a limited amount of people and stuff inside. Software, on the other hand, can be useful early on in the construction process, you can move in long before it’s finished, it has infinite space to accommodate whatever people and stuff you want to put inside, and it can be reconfigured quickly to make it work better for those people. Unfettered by the limits of location, materials, and physics, you can move walls, add stories, and put furniture on the ceiling as easily as if it was a house in a CAD program, because that’s just software, too.
With the easy changes and infinite possibilities the virtual world offers, how can we tell when software is Done? When do we stop work, total up the bill, and move on to the next project?
Definitions of “Done”
By one definition, software is done when it accomplishes its purpose. Like a bridge being considered complete when you can drive across it, an application is done when you can buy something, leave a comment, or upload a video. But software usually has many purposes and as an interactive digital product, “Done” may have nontechnical requirements like performance, aesthetics, behavior, or interactive properties. Defining Done by “I know it when I see it” is risky. Unless you have infinite time and a corresponding budget, you have to be able to objectively define Done and then keep redefining Done as new information comes to light.
Why can’t developers just know what needs to be done to finish the app? “If PromptWorks has the best software engineers,” you might ask, “and they’ve collectively built hundreds of apps, shouldn’t they be able to intuit what makes an app complete and only show me once it’s done?” Well, we try, but the problem is we’re too good at seeing room for improvement. Give a developer infinite time and they’ll never stop coding. Linux has been under continuous active development since 1991 and GNU Emacs has been evolving since 1984! These developers are going to keep innovating, modernizing, and improving until their software is no longer useful or is superseded by another technology.
From our perspective, software is done when the client decides to stop development work, which is usually when the marginal cost of additional features exceeds the marginal value they provide. In accordance with our agile principles, we are adamant about re-assessing the priorities of the features with our clients weekly, so we’re always working on the features that have the highest value first. There’s a long tail of “nice-to-haves,” but at some point the client says, “good enough.”
Budgeting and The Cone of Uncertainty
On top of the features known at the outset, many more potential features are discovered through the process of iterative development. This is why the final software product almost never looks like the plans that were made at the beginning. Using working software firsthand gives you insight into how to make the product better. Additionally, software projects take long enough that the business environment changes significantly between Inception and Done. Managers and executives come and go, new customers emerge with new demands of the product, and the corporate software ecosystem changes while the project is being developed.
All this volatility makes estimating a final cost and completion date with any accuracy nearly impossible at the outset. And while we’ve built hundreds of custom apps, we’ve never built your custom app, so we’re looking into a new, totally different crystal ball every time. The good news is, estimates get better as more features are completed and the software approaches Done. We call this the Cone of Uncertainty.
The final cost of a project might be 4x the initial estimate, or maybe it comes in 25% under budget—you can’t really know at the outset. Anyone who tells you otherwise is wildly optimistic or selling you something! As the project progresses, that envelope of uncertainty gets tighter and tighter until finally the project is finished and the estimate turns into an accounting fact.
Because custom software is built to the client’s ever-changing specifications, the final product always turns out differently than originally conceived. Thus, it makes no sense to track how close we were to our estimates at the completion of a project — it’s like comparing what you wanted to be when you were six years old to your career today. The more successful we are for our clients and their customers, the more they want to engage our services and the further we get from our initial estimates! Clients keep coming back and extending their contract as they see just how good we are and how much we can grow their business.
For us, a big part of estimating projects is aligning expectations and determining risk tolerance. If we estimate a project and don’t get the work because the client doesn’t have the budget, we’ve been successful. They wanted a mansion for the price of a woodshed, but by realistically assessing their desires we avoided failing to meet their expectations. If we do get the project, the estimate has been successful if at the end the client is satisfied with what they ultimately decided to include and what to leave out, even if it looks nothing like their original conception.
How to Know When Software is Done
So, you’re a product owner. Your customers are constantly suggesting new things they want your product to do and your developers could go on enhancing it forever. How do you know when to stop?
Only you can determine how you want to spend your time and money, but here are some techniques to make your project as quick and cost-effective as possible:
Features and bugs need to be prioritized and re-prioritized, typically by the value they provide to the business. I know everything in the backlog might seem essential—especially bugfixes—but it’s absolutely necessary to put them in a linear order. If you must, pick up two story cards and say, “If I could only have one of these, which would it be?” Do that enough times and you’ll have your prioritized backlog of stories.
With the help of a Business Analyst, you’ll want to groom your backlog carefully so there is no unnecessary work or duplicate stories and developers always know what the next top priority is to pick off the top of the stack. Don’t manually assign work to developers or raise up whatever feature is top-of-mind. Siloing and priority churn is one of the biggest killers of development productivity!
Set clear milestones
When stories are worked from greatest to least priority and the team has established a velocity, you can set a milestone and have a good idea what will be accomplished by the date you’ve set. Perhaps you’re working toward an externally-driven milestone, such as a demo at an event or a marketing drop, or maybe it’s just an internal release date.
Regardless, this date should be firm and established well ahead of time, but the scope should be flexible. If stories get done faster than the team’s velocity would predict, a few extra features move above the release line. If things go worse than estimated, the lowest priority stories will need to slip below the line to the next release. Since they were the least important of all the stories, this slippage shouldn’t provoke a crisis. If it does, you’re either under-resourced or not prioritizing correctly.
Don’t rush features into a release
The three corners of the Iron Triangle are resources, schedule, and scope. As Yvonne pointed out in her Iron Triangle explanation, resources and schedule are usually fixed, so if scope can’t flex, quality invariably suffers. You shouldn’t “whip the ponies harder” to get more features into the release or you’ll ship a product with more defects and technical debt. With proper prioritization and an automated release process, releases are easy and frequent enough that the feature can just wait for the next release. “The Swiss don’t run for trains” and you shouldn’t hurry the last couple features or delay the release; the next train will be along in a few minutes. If you weren’t prepared to live without those features, they should have been prioritized above something else.
Flexibility Gets Software Done
By embracing the nature of software development and following these practices, we ensure a safe, predictable, and low-stress process of getting software Done. If you’ve been around the industry long enough, you know that this isn’t typical. Usually an army of personnel draw up specifications, budgets, and schedules, and then over the course of the project they’re all blown to bits with lots of stress, agonizing, and production mistakes as new requirements are uncovered, the business environment changes, and external dependencies aren’t as reliable as believed. The majority of software projects run over budget or fail entirely because product owners asked for estimates, were given “scientific wild-ass guesses,” and then treated them as gospel.
At PromptWorks, we’ve had a lot of success with a software development process that is more honest and realistic than telling a client a guess pulled out of the air and then managing missed expectations later. Instead, we give custom software clients the flexibility to change their minds as we iterate and new information and requirements arise. We’ve found that once they come to trust our expertise, professionalism, and carefully-refined process, clients become more confident in the product they are delivering and are happier with the results.
For more on these topics, read The Nature of Software Development by Ron Jeffries.