This image excellently sums up one of the most important adjustments I made to my software development philosophy this year, both personally and professionally. (I can’t find who made it, and would love to offer credit if anyone could clue me in.)
The image succinctly and cleverly illustrates the concept of “minimum viable product” in terms of two strategies for delivering a project, here represented by an automobile. The first route — the traditional way, it implies — has you build tires, then axles, then a chassis, and so on. In the end, you connect everything together and there’s your car. You’d have every right to call each step a milestone; the car does need tires, after all, and you did build them, so check that off the list and take the weekend off, right?
However, the frownyfaces over every step until final delivery show that the thing built so far isn’t even a thing; it’s just a pile of components, full of potential but of no immediate use to anyone. If the person waiting for the car is someone besides you-the-builder, then waiting is all they can do. And all you can do for them, today, is to continually reassure them that you’re hard at work. Perhaps you’ll show them evidence of the steadily growing stack of nonfunctional components you’re generating, which by definition they have no way to test or critique, let alone get any practical use from.
The image’s second route shares the same endpoint of delivering a car, but with entirely different steps towards it. Now, the first milestone is a skateboard. To reach the second milestone, we add features to the skateboard, and now it’s a scooter. Add a gear-driven propulsion system and a seat, and we have a bicycle. Upgrade that to use self-propulsion instead, and we reach the penultimate milestone of a working motorcycle. Finally we focus on variously bulking up the vehicle’s capacity, and we arrive at the deliverable car.
And now the judgmental faces over every milestone smile, because at every point you have something immediately useful. Until you get to that last step you haven’t finished yet; we certainly can’t consider a scooter as fulfilling a request to develop a car that seats four. But you do have something that the person waiting for that car — whether yourself, or someone else — can start putting to use in the meantime.
Yes, besides relying on a fantastically abstract way of thinking about automotive engineering, this metaphor only works if we can agree with our smiley-faced customer that “I need a car” can be recast as “I need a way to get around town that’s faster than walking, and I feel that a car would suit my needs best.” But if we can do that in a way that makes sense for the project and for the customer’s needs, then we have every reason to take the latter route.
This way, after the first milestone, the customer already begins to use our work, and can offer us feedback. They’re starting to move around a little faster and gaining practical experience as to the implications of this activity, and we can use this to revisit and refine our goals together. (Maybe neither of us realized the primary importance of brakes, at the start of the project.) They can also tell us, long before the project reaches terminal levels of complexity, how well we’re meeting their vision for various features. If my concept of steering is backwards from the customer’s expectations, I’d rather they have a chance to let me know after taking the bicycle milestone for a spin than after taking the automobile deliverable on its maiden voyage.
And heck, maybe when we get to the bicycle, their funding runs out. But now they have a beautifully working custom bike, and we got paid for delivering them one, even if that wasn’t the original plan. How much happier both parties are, in this case, versus the one where we halt a project after producing only a tumble of inert parts?
In my career I have had to pull a tarp over a pile of painstakingly hand-made and completely useless software components far too many times. At the start of this year, I read Practices of an Agile Developer by Subramaniam and Hunt, and took its core messages as profound revelations. I applied them immediately to two large software projects I had in my workshop: one a from-scratch rewrite of a local ferry company’s ancient and rickety reservation system, and one a from-scratch rewrite of the Interactive Fiction Competition’s ancient and rickety website. I believe that this philosophical pivot saved both projects from delay at the least and disaster at the most.
After taking up agile thinking (and that’s “agile” with a small “a” — no scrums or standups for me), I began using tools like Pivotal Tracker to break large projects like these up into milestones defined less as “whew, OK, this giant category of business logic is all done” and more as “The customer can now do this”, for steadily advancing values of this.
And so, I launched the new ifcomp.org website in April, after focusing only on its new design, and the various essays and other pieces of static content I made for it, not worrying at all about how people would enter works into the competition a few months later. And it worked! I received a lot of great feedback about the site early on, and (after I did finish the entry component, right on time) more people entered the 20th annual IFComp than they had in many years prior. I viewed the remaining work as a series of deadlined milestones, instead of one fat ultimate deadline containing everything. While this pattern felt strange and even precarious at times, in retrospect, I could not imagine finishing this project with as much success and energy in any other way.
Similarly, at this time last year, I felt really good about the state of the ferry company’s reservation system; I’d written its whole backend, a big set of object classes tied to many empty database tables, before taking my Christmas vacation. Everything was on schedule! And then I read this book and that all fell away. I remembered how my client would call me and ask how it was going, and I’d say it was going fine, and that would be about all I could say, because it was the truth? Good lord, how this book helped me to see that I was not doing OK by them.
I can’t exactly say that I threw all that earlier work away, but I did immediately take an entirely different tack with it. As soon as I could — it took months, from the position I’d put myself, but it was still as soon as I could — a colleague and I started to deliver working components of the reservation system to the client, starting with various customizable but read-only reports that used real-life data. We left the ability to actually create new reservations as a future milestone; the client continued to use their old system for this purpose in the meantime.
We all found the benefits of delivering viable, usable milestones brilliantly obvious. Our working sooner with real-world data crucially updated our perceptions about the system’s needs, as did the client’s earlier exposure to the style and quality of our work. They had the power to request changes well before the codebase had grown to its full expected size, when changes become proportionately more expensive to enact. How much better our work became, and how happier the users felt with the work, versus when we treated milestones as mere boxes to check off as we keep hammering away at the machine in darkness for weeks at a stretch.
And so I feel great to end the year by shipping Plerd, just days old and missing a great deal of eventual features. But it does exactly the main thing I wanted, and here I am blogging again. I do not think I’d have been able to do this, five years ago; I would have tweaked and tinkered at Plerd for months, sharing it with nobody, and certainly not using it. It wasn’t complete yet! How could I possibly use it?
Well, that’s an excellent point. So, here’s looking to a new year of great projects built while embracing the reality that we will never complete them, so that we instead might ship them, early and often, again and again.