Joel Spolsky recently wrote an article about “The Duct Tape Programmer” in which he espouses the benefits of a pragmatic approach to creating (and thus shipping) software:
Duct tape programmers are pragmatic. Zawinski popularized Richard Gabriel’s precept of Worse is Better. 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.
I think this approach makes sense to a degree, though there are certainly some good counter-arguments that have been made. What interested me about his post, though, was how approaches to “shipping software” can sometimes differ in large enterprises when compared to shipping commercial software to end-users or to producing applications in small- or medium-sized business.
This isn’t to say that creating a good product – for any audience, in any setting – is easy. It’s not. The types of challenges, though, are different. This is why Joel’s comments help highlight the differences between developing “enterprise applications” – by which I mean applications, increasingly in the form of rich internet applications, that are consumed by millions of customers – and more traditional COTS applications or smaller internet-based offerings. Ability to manage scale is a feature just like shipping software.
The reason for the difference is that the scale (in terms of users) amplifies all aspects of an application: obviously its ability to handle increasing volume, but also bad (and good) design decisions, the ability to react to new requirements/features, and the quality of all those “pragmatic” decisions. The latitude to make misjudgments when trying to being pragmatic with a web-based application supporting a million concurrent users is much more constrained than one that supports three hundred concurrent users.
The challenge for the managers, developers and architects of enterprise-scale applications is how to avoid having to make these kinds of decisions in the first place. This is one area where Joel absolutely nails it: simplicity is key. The number one way to avoid having to make difficult, pragmatic trade-offs is to keep the solution simple. In a series of upcoming posts on resiliency, I’ll explore this theme in the context of infrastructure, software development and integration services.
But what if you already have a complex solution? What if an aspect of your solution is complex by necessity? How do you know which trade-offs are “safe” and which will cause failures, customer frustration, or slow time-to-market for future features? Experience counts for a lot, but is it good business to make these decisions on instinct? No – but lots of companies do it.
While there are very experienced, talented folks who can make these decisions by gut feel, they’re few and far between. It’s not a repeatable process. It can’t be explained to shareholders. It can’t be quantified. Analysis and data are required to make informed trade-offs rather than instinctual gambles on what will work. This is why an integrated approach to solution architecture, software design and development, infrastructure support, people management and process control is required. These decisions get made based on data from detailed failure-mode analysis. They’re supported by data collected from the operating environment about user behavior. They’re mitigated through tightly controlled processes and a quality of communication that is difficult to achieve in your typical Fortune 100 company.
The most ideal condition is that the people making trade-offs about features, functionality, and complexity know exactly how the value of each and every transaction or feature used by a user.
- The business “value” (revenue generated, costs avoided, etc.) of each transaction/feature
- The frequency of use of each transaction/feature
- The likelihood of a particular failure mode occurring, which transactions/features are affected, how it will be detected, and how long it takes to fix
While this pinnacle of knowledge cannot always be achieved, it can be approximated more easily than many people believe. It requires changing how design is approached, buy-in from business partners, and the ability to spend time during the design process to perform the necessary analysis. It’s not easy, but neither is competing at enterprise-scale.
This is why simplicity is important: the less complex a solution is, the easier it is to gain this insight. Spending time on simplicity pays off.