I’ve posited and shared many perspectives on software development / product design over the years and this will be the last one that I do on this blog.
And it’s not that the other “iterations” of my thoughts aren’t true or that they weren’t (directionally) correct; rather, they weren’t as-mature as it is today. This is, like most things, a process of self-discovery, not necessarily about adopting or using “better” workflows or systems or tools.
I thought I knew how to build software when I was younger. Now, I’m not entirely sure how much of it gets done, at all. Sobriety suggests that I really never knew. It’s because I was focused on the wrong things; a slightly-nuanced but important difference between
outputs and real
The reality is that any and all of those previous positions were “best guesses” at the time and although a handful of those posits remain true, most of them are embarrassing in their superficiality and detachment from reality.
Why? Because I was scared to build and design software the way that I wanted and most-naturally behaved and my insecurity dictated that it’s better to borrow or copy existing models that seem proven and effective than develop and curate my own.
I was wrong. I now know that building anything great necessarily requires the art to naturally flow from the artist (and back again). A great piece of software isn’t defined by the workflows or methodologies one uses to create it but rather the proximity and intimacy between the creator and their creation.
Truly, world-class software is the reflection of its creators and the more that reflection accurately mirrors the actual behaviors of the designers of the system, the better. Increase the fidelity and alignment in the principal system and you increase fundamental integrity which has many natural upsides; success in the market and with customers is just one of them.
With that in mind, here are some important and hard-earned truths on software and product design that work for me and, more generally, the teams that I seem to get along well enough to do serious damage with:
- Trust is everything. Psychological safety is the foundation and without it you will not trust or respect anyone on the team enough to do serious and important work. Great software is built upon trust; trust in others and in their respective work and contributions.
- The system was built for the team, not the team for the system. This means that you should be more than willing to throw away any — and all! — system(s) that get in the way of fundamental production. Most folks have too many systems but are also too prideful to rework, remove, or reconsider them, to their own detriment.
- The only reason you write business software is to scale business outcomes. That’s it. If you can achieve continually growing, positive outcomes for the enterprise then nothing else matters. Really. For instance, no one cares what “agile” methodology your team uses or your specific product management tooling when the business is kicking ass (and taking names). The mistake is believing in your own shit too much.
- Software is either useful or it is not. “Great” business software is simply defined by its ability achieve positive business outcomes and any software that doesn’t do this is shit. It’s a bit like PMF: You either have it or you don’t.
- To make #4 even more difficult is the fact that there are no hard-and-fast rules about how you get there. Just get there, however you can. Even more maddening is the fact that the time required to get there and the speed of iteration / cycle time isn’t nearly as important as you’ve been led to believe. “Agility” is not the same thing as “going fast” or even a description of cycle pathing, time, or performance; it’s just a system to inform one’s decision-making.
- The what, when, why, where, and how all combine into a singular perspective and (meta) system of thinking for your software and team. And, if you change one input you have to consider every possible output. It’s all connected. Experienced software designers know that you cannot improve a system by independently tweaking or improving its parts, especially if you’re building something truly innovative and new. This is difficult to fully appreciate when you’re earlier in your career and impossible to “unsee” once you’re weathered.
- Effective software is simple software because simplicity is predictable and predictable software is effective software because it never leaves you guessing its own outcomes. As I like to say, a lot, simple systems work best.
- It is very useful (and reasonable) to actually like writing software but it is not a requirement to write useful software. Just like writing emails (or anything for that matter). I know this because I do not like writing software.
- Quality software requires a high-degree of quality communication and the “quality” is entirely determined by the culture in which the software is being built and has almost nothing to do with how much or how often a team connects, or even the format for that matter (text, video, audio). Sometimes, all you can hear is silence and you know things are working as they should be.
- Software is never finished, only abandoned.
I imagine that my viewpoints will continue to evolve, mature, and rebase as I continue the never-ending quest to create scalable value through software; the quest and adventure never really ends. Except I’ll be sharing those in the metaverse.
How fun, how entertaining, how liberating.