Product Focused Design: Or, "How I Learned To Stop Tinkering and Ship"
The perfect is the enemy of the good. So either we'll ship imperfect software or we'll ship nothing at all!
All horror stories begin with a terrifying opening scene. In this case, one such heart-thumping experience appears below:
Sometimes, you’re on a team, and you’re busy banging out the code, and somebody comes up to your desk, coffee mug in hand, and starts rattling on about how if you use multi-threaded COM apartments, your app will be 34% sparklier, and it’s not even that hard, because he’s written a bunch of templates, and all you have to do is multiply-inherit from 17 of his templates, each taking an average of four arguments, and you barely even have to write the body of the function. It’s just a gigantic list of multiple-inheritance from different classes and hey, presto, multi-apartment threaded COM. And your eyes are swimming, and you have no friggin’ idea what this frigtard is talking about, but he just won’t go away, and even if he does go away, he’s just going back into his office to write more of his clever classes constructed entirely from multiple inheritance from templates, without a single implementation body at all, and it’s going to crash like crazy, and you’re going to get paged at night to come in and try to figure it out because he’ll be at some goddamn “design patterns” meetup.
- Joel Spolsky
Why is our hypothetical, multiple-inheritance template-lover a pain in our collective arse? Because he’s not focused on the product. He’s interested in complex-patterns, impressive feats of over-engineering, assembling a whole litany of things no one will ever need, and well, anything except the product and its users. And in case it was unclear to anyone attempting to use lines of code in pursuit of earning one’s daily bread, it’s about the [expletive] product. Products are used by users. You’re making this for them.
We do not write software simply to experiment with something interesting. We do not compose lines of code to demonstrate intellect. Code is not an exposition for ego-stroking. Code and computers are tools for building products, much like brick and mortar, wood and nails, or flour and sugar. And those tools are deployed in the service of delivering user value - nothing more. Whatever “best practice” is bandied about in Boardrooms today will be derided tomorrow. Product-focused design, to paraphrase Vince Lombardi1, is not the best practice, it is the only practice.
It is often undesirable to go for the right thing first. It is better to get half of the right thing available so that it spreads like a virus. Once people are hooked on it, take the time to improve it to 90% of the right thing.
- Richard Gabriel
Truly behaving as a “product-first” team is harder than being “design-first” or “developer-first.” Rigid standards, applied across all projects, might lead to a false sense of safety and comfort. Alas, to quote the Joker, “you have all these rules, and you think they’ll save you.” This might keep us away from certain horrifying minima (like, say, a grotesque design or a kafka-esque torture chamber for developers), but we’ll be trapped at a local maximum2, and never even get a whiff of the global maximum - the best possible product that users will love. Finding that best product requires a trip into the grey areas of creativity, ingenuity, and good judgment. Maybe the Joker was right after all?
Voltaire once wrote, “le mieux est l’ennemi du bien.3” Translated, it reads “the perfect is the enemy of the good.” While most literary scholars agree that Voltaire did not develop software, his wisdom remains a relevant warning to would-be engineers. Don’t overengineer. Worrying about the beauty and elegance of your code or your UI leads to aesthetically-pleasing, trend-following, complicated, pretty shit that no one has time to develop or maintain. And to be clear, designing and developing features that don’t work is a recipe for financial disaster. It is worth noting that the more code you write, the more bugs you will create so if you aren’t gonna need it (YAGNI), you’re creating bugs, making the development of new features ever more prohibitive, and you aren’t doing the simplest thing that can possibly work (DTSTTCPW). Basically, the value of each new feature diminishes over time. The number of bugs you create does not. A mathematical proof can be written, but the TL/DR is “eventually, you’re creating more problems than you can solve and costing more money cleaning up the messes you’re making than the value you’re adding to the product.”
Organization of software systems should lie somewhere between the extremes of the horrific tangled mess of code hoarders, and the antiseptic cleanliness seen in the pages of interior decorating magazines and home sales brochures.
This is not something I had considered or expressed before; though it has always been something I’ve sheepishly practiced…
- Uncle Bob
Again, true beauty and wisdom lies in the grey. Rules don’t save you.
Mediocre programmers are, frankly, defensive about this, … they don’t want to admit that they’re not able to write this super-complicated code, so they let the bullies on their team plow away with some godforsaken template architecture in C++ because otherwise they’d have to admit that they just don’t feel smart enough to use what would otherwise be a perfectly good programming technique FOR SPOCK. Duct tape programmers don’t give a shit about what you think about them. They stick to simple basic and easy to use tools and use the extra brainpower that these tools leave them to write more useful features for their customers.
A 50% good solution that people actually have solves more problems and survives longer than a 99% solution that nobody has because it’s in your lab where you’re endlessly polishing the damn thing. Shipping is a feature. A really important feature. Your product must have it.
- Joel Spolsky
In this case, Spolsky’s quote has its own famous TL/DR:
A good plan violently executed now is better than a perfect plan executed next week.
- George S. Patton
Most historians agree that general Patton, like Voltaire, did not write code. He probably did not bring his laptop to the Battle of the Bulge. He did, however, get shit done with ruthless efficiency.4 While I wouldn’t want Patton as my manager, I’ll bet his teams would’ve shipped.
Who can justify the expense of a six-lane highway through the middle of a small town that anticipates growth? Who would want such a road through their town?
- Robert C. Martin
That last one is poignant. Even with time, money, an established user base, and some loyalty, the goal is still “90% of the right thing.” Trying to build 100% of the right thing is the perfect plan next week, the six-lane highway through the small town, the metaphor to end all metaphors. It ain’t happening. Plan accordingly.
Be realistic. Set and understand priorities. Analyze and discuss trade-offs early and often. No, even earlier and even more often. Overcommunicate. Ask with the type of regularity that suggests a recurring sitcom joke, “does this thing I’m going to do accomplish the real goals here?” If it does not further the product in a manner that the moment demands, that’s your cue to do basically anything else, including nothing at all. Unwritten lines of code contain no bugs. Seriously. It’s been tested. I’ve never had a single unit test fail on a line I did not write. Amazing. 100% guaranteed.
Work closely with team members to design and develop the best thing possible, given the constraints posed by reality. Adopt an iterative approach–reality is a dynamic pain in the arse and the specific nature of those pains and those arses emerges with each passing day. Manage technical and design debt. Overcommunicate often about that too. No, even more often. Seriously.
And at the end of the day, ship the fucking thing! It’s great to rewrite your code and make it cleaner and by the third time it’ll actually be pretty. But that’s not the point-you’re not here to write code; you’re here to ship products.
- Jwz
After all, there are only two types of projects. Those that are perfect5, and those that are completed. Which do you suspect the user prefers?
1
Famed football coach of the Green Bay Packers in the 60’s, well-known for having coined the phrase, “winning isn’t everything, it’s the only thing.” Most likely, he did not originate it, but assuredly made it famous, ruining the more conciliatory attempts of Little League coaches thereafter who informed their players that “winning isn’t everything,” only to receive the second-half of the quotation from some smart aleck on the bench with a mouth full of sunflower seeds and Big League Chew.
2
Local maxima are like when you climb up to the top of a mountain, feel really accomplished for having done so, but need to accept that in the same range, there’s a taller peak. Now imagine you’re an algorithm that only climbs uphill. Now you’re stuck, because every direction is down. There’s no path to the higher summit without some downhill wandering along the way. Also, algorithms generally cannot look out into the distance to see the higher peak, but then, they also tend to avoid blisters and overspending at REI.
3
I mean, he didn’t actually. There were other folks before, but still, possession is 90% of the law, and Voltaire died with the quote in his possession. Or something like that. Go tend some gardens and leave me alone.
4
The third weapon of the Spanish Inquisition. The first two are “fear” and “surprise.” The fourth is “an almost fanatical devotion to the pope.” Maybe this reference caught you off guard, but then, no one really expects a reference to the Spanish Inquisition sketch.
5
Einstein said famously, “everything should be as simple as it can be, but not simpler.” At AE, our projects are as perfect as can be achieved while still being completed - but no more so.
No one works with an agency just because they have a clever blog. To work with my colleagues, who spend their days developing software that turns your MVP into an IPO, rather than writing blog posts, click here (Then you can spend your time reading our content from your yacht / pied-a-terre). If you can’t afford to build an app, you can always learn how to succeed in tech by reading other essays.
Product Focused Design: Or, "How I Learned To Stop Tinkering and Ship"
The perfect is the enemy of the good. So either we'll ship imperfect software or we'll ship nothing at all!
All horror stories begin with a terrifying opening scene. In this case, one such heart-thumping experience appears below:
Sometimes, you’re on a team, and you’re busy banging out the code, and somebody comes up to your desk, coffee mug in hand, and starts rattling on about how if you use multi-threaded COM apartments, your app will be 34% sparklier, and it’s not even that hard, because he’s written a bunch of templates, and all you have to do is multiply-inherit from 17 of his templates, each taking an average of four arguments, and you barely even have to write the body of the function. It’s just a gigantic list of multiple-inheritance from different classes and hey, presto, multi-apartment threaded COM. And your eyes are swimming, and you have no friggin’ idea what this frigtard is talking about, but he just won’t go away, and even if he does go away, he’s just going back into his office to write more of his clever classes constructed entirely from multiple inheritance from templates, without a single implementation body at all, and it’s going to crash like crazy, and you’re going to get paged at night to come in and try to figure it out because he’ll be at some goddamn “design patterns” meetup.
- Joel Spolsky
Why is our hypothetical, multiple-inheritance template-lover a pain in our collective arse? Because he’s not focused on the product. He’s interested in complex-patterns, impressive feats of over-engineering, assembling a whole litany of things no one will ever need, and well, anything except the product and its users. And in case it was unclear to anyone attempting to use lines of code in pursuit of earning one’s daily bread, it’s about the [expletive] product. Products are used by users. You’re making this for them.
We do not write software simply to experiment with something interesting. We do not compose lines of code to demonstrate intellect. Code is not an exposition for ego-stroking. Code and computers are tools for building products, much like brick and mortar, wood and nails, or flour and sugar. And those tools are deployed in the service of delivering user value - nothing more. Whatever “best practice” is bandied about in Boardrooms today will be derided tomorrow. Product-focused design, to paraphrase Vince Lombardi1, is not the best practice, it is the only practice.
It is often undesirable to go for the right thing first. It is better to get half of the right thing available so that it spreads like a virus. Once people are hooked on it, take the time to improve it to 90% of the right thing.
- Richard Gabriel
Truly behaving as a “product-first” team is harder than being “design-first” or “developer-first.” Rigid standards, applied across all projects, might lead to a false sense of safety and comfort. Alas, to quote the Joker, “you have all these rules, and you think they’ll save you.” This might keep us away from certain horrifying minima (like, say, a grotesque design or a kafka-esque torture chamber for developers), but we’ll be trapped at a local maximum2, and never even get a whiff of the global maximum - the best possible product that users will love. Finding that best product requires a trip into the grey areas of creativity, ingenuity, and good judgment. Maybe the Joker was right after all?
Voltaire once wrote, “le mieux est l’ennemi du bien.3” Translated, it reads “the perfect is the enemy of the good.” While most literary scholars agree that Voltaire did not develop software, his wisdom remains a relevant warning to would-be engineers. Don’t overengineer. Worrying about the beauty and elegance of your code or your UI leads to aesthetically-pleasing, trend-following, complicated, pretty shit that no one has time to develop or maintain. And to be clear, designing and developing features that don’t work is a recipe for financial disaster. It is worth noting that the more code you write, the more bugs you will create so if you aren’t gonna need it (YAGNI), you’re creating bugs, making the development of new features ever more prohibitive, and you aren’t doing the simplest thing that can possibly work (DTSTTCPW). Basically, the value of each new feature diminishes over time. The number of bugs you create does not. A mathematical proof can be written, but the TL/DR is “eventually, you’re creating more problems than you can solve and costing more money cleaning up the messes you’re making than the value you’re adding to the product.”
Organization of software systems should lie somewhere between the extremes of the horrific tangled mess of code hoarders, and the antiseptic cleanliness seen in the pages of interior decorating magazines and home sales brochures.
This is not something I had considered or expressed before; though it has always been something I’ve sheepishly practiced…
- Uncle Bob
Again, true beauty and wisdom lies in the grey. Rules don’t save you.
Mediocre programmers are, frankly, defensive about this, … they don’t want to admit that they’re not able to write this super-complicated code, so they let the bullies on their team plow away with some godforsaken template architecture in C++ because otherwise they’d have to admit that they just don’t feel smart enough to use what would otherwise be a perfectly good programming technique FOR SPOCK. Duct tape programmers don’t give a shit about what you think about them. They stick to simple basic and easy to use tools and use the extra brainpower that these tools leave them to write more useful features for their customers.
A 50% good solution that people actually have solves more problems and survives longer than a 99% solution that nobody has because it’s in your lab where you’re endlessly polishing the damn thing. Shipping is a feature. A really important feature. Your product must have it.
- Joel Spolsky
In this case, Spolsky’s quote has its own famous TL/DR:
A good plan violently executed now is better than a perfect plan executed next week.
- George S. Patton
Most historians agree that general Patton, like Voltaire, did not write code. He probably did not bring his laptop to the Battle of the Bulge. He did, however, get shit done with ruthless efficiency.4 While I wouldn’t want Patton as my manager, I’ll bet his teams would’ve shipped.
Who can justify the expense of a six-lane highway through the middle of a small town that anticipates growth? Who would want such a road through their town?
- Robert C. Martin
That last one is poignant. Even with time, money, an established user base, and some loyalty, the goal is still “90% of the right thing.” Trying to build 100% of the right thing is the perfect plan next week, the six-lane highway through the small town, the metaphor to end all metaphors. It ain’t happening. Plan accordingly.
Be realistic. Set and understand priorities. Analyze and discuss trade-offs early and often. No, even earlier and even more often. Overcommunicate. Ask with the type of regularity that suggests a recurring sitcom joke, “does this thing I’m going to do accomplish the real goals here?” If it does not further the product in a manner that the moment demands, that’s your cue to do basically anything else, including nothing at all. Unwritten lines of code contain no bugs. Seriously. It’s been tested. I’ve never had a single unit test fail on a line I did not write. Amazing. 100% guaranteed.
Work closely with team members to design and develop the best thing possible, given the constraints posed by reality. Adopt an iterative approach–reality is a dynamic pain in the arse and the specific nature of those pains and those arses emerges with each passing day. Manage technical and design debt. Overcommunicate often about that too. No, even more often. Seriously.
And at the end of the day, ship the fucking thing! It’s great to rewrite your code and make it cleaner and by the third time it’ll actually be pretty. But that’s not the point-you’re not here to write code; you’re here to ship products.
- Jwz
After all, there are only two types of projects. Those that are perfect5, and those that are completed. Which do you suspect the user prefers?
1
Famed football coach of the Green Bay Packers in the 60’s, well-known for having coined the phrase, “winning isn’t everything, it’s the only thing.” Most likely, he did not originate it, but assuredly made it famous, ruining the more conciliatory attempts of Little League coaches thereafter who informed their players that “winning isn’t everything,” only to receive the second-half of the quotation from some smart aleck on the bench with a mouth full of sunflower seeds and Big League Chew.
2
Local maxima are like when you climb up to the top of a mountain, feel really accomplished for having done so, but need to accept that in the same range, there’s a taller peak. Now imagine you’re an algorithm that only climbs uphill. Now you’re stuck, because every direction is down. There’s no path to the higher summit without some downhill wandering along the way. Also, algorithms generally cannot look out into the distance to see the higher peak, but then, they also tend to avoid blisters and overspending at REI.
3
I mean, he didn’t actually. There were other folks before, but still, possession is 90% of the law, and Voltaire died with the quote in his possession. Or something like that. Go tend some gardens and leave me alone.
4
The third weapon of the Spanish Inquisition. The first two are “fear” and “surprise.” The fourth is “an almost fanatical devotion to the pope.” Maybe this reference caught you off guard, but then, no one really expects a reference to the Spanish Inquisition sketch.
5
Einstein said famously, “everything should be as simple as it can be, but not simpler.” At AE, our projects are as perfect as can be achieved while still being completed - but no more so.