Wednesday, May 2, 2007

Ridiculous Simplicity (#1)

Bookmark and Share

"Simplicity--the art of maximizing the amount of work not done--is essential." (http://agilemanifesto.org/principles.html)

When I was a kid and would start to make something into a big deal, I remember my mom accusing me of making a "mountain out of a mole hill." That may be an expression that only makes sense here in the southern part of the US, but it seems to be applicable to projects I see all over the world. The systems we undertake today, and the technologies we have at our disposal, certainly allow us to make mountains. Of course, we all know mountains tend to be rigid and inflexible - immovable. In response, a deliberate practice - a core value - of delivering simplicity has become even more important in today's IT climate. What I'm thinking about here spans both the problem space and the solution space... we must simplify the problems and simplify the solutions. But what does that mean?

Ridiculous Simplicity in the Problem Space

I bet we all can think of plenty of examples where we allowed the business problem to get out of hand. Allowed it to grow nearly unbounded. I've witnessed a couple of projects over my career where "we" fell into the "boil the ocean" trap in the problem space, imagining that a product could not go to market unless it had nearly every conceivable feature. We allow the project to get bogged down in "requirements gathering" and don't demonstrate the collective discipline (and confidence) necessary to establish direction and make hard decisions on trade-offs in the market. I'm thinking about things like which features are really required and which are not. It's true that there are market situations where a product should not be released without all the "bells and whistles" or "this and that", but those scenarios are rare. Generally speaking, we do our business partners a tremendous favor by encouraging an environment that releases "right-sized" product and builds on it over subsequent releases.

This reminds me of a story... About 14 years ago, when I first left the US Air Force, I was working with a team building an internal account payables system. Users of the system choose the appropriate cost center upon login, and about 10% of the users had rights to access more than one cost center. When the user was ready to operate on a different cost center, they would have to logout and then log back in, this time selecting the alternate cost center. I made a case that we should change the screen design to allow the user to choose a different cost center without logging out. This alternative design would simply place a drop down list or something to that effect in the product. The user would select the appropriate cost center from the list.

My boss at that time argued against this approach and helped reinforce the importance of managing scope on the project - and on the product. It's not just the 15 minutes that it would take to add the feature (and that's really all it would have taken), but it was also the longer term consideration such as "care and feeding" of this capability, the constraints it introduced on the future evolution of the architecture and design, etc. It was a 15 minute change request in this one project, but it had hours and hours of impact over the life of the product. My boss insisted, "one of my principle responsibilities is to control this scope." I learned a lot from this guy. I think we all can. Today, many of us can think of projects where we refused to let the "15 minute feature" get in, but also the dozens of other features, functions, etc, that ultimately lead to the death of a product or project - crushed under it's own weight. Where successfully managed, these products remain lean and responsive to change, able to keep up with evolving demands over a healthy and long life.

Ridiculous Simplicity in the Solution Space

We can see similar characteristics on the solution side. Most developers I know really care about the "right-ness" of the design and implementation of the product. Their heart is in it, and they want it to be "perfect." And high-quality, precise work is always right and proper. We should never settle for mediocrity. The trouble we seem to run into, however, is in the definition of "right" or of "mediocrity." How do we assess the "right" design and the "best" implementation? The tendency seems to slant towards more or bigger or complex, when we should evaluate a solution based on the degree to which it satisfies the requirement and on its simplicity - the elegance of its simplicity. Without direct energy applied, a team frequently migrates towards what I like to refer to as "someday maybe" design. The design begins to get tweaked in sometimes subtle ways to account for the idea that "someday maybe" we'll need to be able to do X, Y, or Z. The "right" design satisfies today's requirements without trying to predict the future, recognizing that the chances of predicting correctly have been shown to be very slim, AND, when the future comes and we know what it holds, we can change the design. At that point, we'll be in the advantageous position of knowing precisely what's needed (based on actual data and experience as opposed to predictions), and we'll be able to get the design "right". I'll assert then, that the best design is the one that satisfies today's requirements while leaving options open for tomorrow's.

Just one brief example while we're on the topic of simplicity in the solution space. I recently witnessed a project where there was a fairly straightforward b2b web service interface that precisely satisfied the market needs. Falling directly into the "someday maybe" trap, the team added additional attributes to this interface - attributes that were not used in any fashion today - just in case they may be valuable to the business in the future. Compounding the situation, the team built a separate database to store the service response and create reports to demonstrate whether or not the b2b partners were populating the unused fields. The cost to the business is significant as a result of design by prediction rather than data, architectural inflexibility, additional scenarios and code paths to test and design around in future releases, client implementations and documentation confusion, etc.

Wrapping It Up

On my teams, we incessantly strive to find the most straight-forward solutions to problems and execute those solutions with pinpoint accuracy. You’ll hear team members and managers echo the phrase “do the simplest thing that could possibly work” and challenging one another with "is that really the simplest thing?"

This is a key principle of an agile, nimble, and responsive development team. And interestingly, this principle manifests itself in the products produced by such team. The products themselves exhibit agile, nimble, and adaptable characteristics, essentially mirroring the nature of the team that created them.

I'll wrap up with this quote from Dr. Paul MacCready:

"Treat every problem as if it can be solved with ridiculous simplicity. The time you save on the 98% of problems for which this is true will give you ridiculous resources to apply to the other 2%."

I've consistently found this to be overwhelmingly true. Without the precise data to back it up, I'll assert that a focus on simplicity reduces the overall work effort on a project by up to 50% and enables the Business/IT partnership to more quickly deliver higher quality software that satisfies the market needs. These same products then respond to the pressure of market change and evolution in a much more resilient manner, ultimately leading to higher profitability and better performance in the marketplace.

One last thing... I would expect these thoughts to stir questions on topics such as the following, each of which we'll take some time to explore in the near future:

1. Cost of Change curve
2. The necessity of automated testing
3. The YAGNI (you ain't gonna need it) principle
4. Refactoring


No comments: