Applying Murphy's Law to Java Development
- Engineering Complexity
- Birth of Murphy for Java
- People = Problems
- Education Through Pain Management
- The Twenty-Cent Solution
- Fraternal Clones
- "We Lost the Napkin"
- The Devil in Blue Jeans
- Jack and the Beanstalk
- The Slashdot Effect
- The Funhouse Microphone
- That "New Car" Smell
- If I Can See It, It Must Be Wrong
- The Ugly American
- Murphy's Law
- Use Egg Cartons
- Conclusion
As an architect, I am often called in to recover projects that are in trouble. I also get projects that were blissfully unaware that they were in trouble but were about to crash and burn. When you look at such failures, there are often clear scapegoats in the form of design, people, third-party software, tools, users, and even politics. Nevertheless, the reason the failure happened in the first place is entirely a different matter. The true problem was either that risks had not been considered or risk analysis did not result in a plan to overcome and reduce the risks.
The subject here is successful Java projects. To create success, we need to study failure first. My weapon of choice is Murphy's Law: If it can go wrong, it will.
Murphy was a real person. He helped invent the idea of having backups for both jet aircraft and even human space flight with his involvement on the Apollo moon missions. "If it can go wrong, it will" was actually an explanation for redundant systemsnot just a funny witticism. If you assume that a piece of equipment might fail, and eventually will, you should have a plan for when it does. Your only recourse is to have one or more backup systems so that when one system fails it's highly probable that the backup will be okay and able to do the work. Thus, flying based on the odds of failure was born.
The linking of Murphy's Law and backups has failed in brilliant irony. Luckily, Murphy had a son (a backup) who has helped shine up the family name. Murphy's son, Edward A. Murphy III, explained Murphy's Law best in a letter to the editor of Scientific American:
Murphy's Law actually refers to the CERTAINTY of failure. It is a call for determining the likely causes of failure in advance and acting to prevent a problem before it occurs. In the example of flipping toast, my father would not have stood by and watched the slice fall onto its buttered side. Instead he would have figured out a way to prevent the fall or at least ensure that the toast would fall butter-side up.E. A. Murphy III, Scientific American 8/97
I have continued the cause of Murphy myself. What follows are my thoughts on how to apply Murphy's Law to softwarespecifically, to Java development. I have been maintaining these laws for several years and have added a few new laws over time. The application is simple and straightforward.
NOTE
I don't always get specific in some descriptions; the barest descriptions can elicit the most paranoia.
Before we get to the laws, let's cover a little background on why we need them.
Engineering Complexity
Why don't airplanes crash as often as software applications fail?
When an airplane is designed, aerodynamics, material strengths, stresses, and other factors derived from physics, engineering, and chemistry are used to create predictable and repeatable results. There is some variation from calculations, but usually aircraft designers simulate and test assumptions to ensure correctness.
How an airplane is used is also well known. The airplane is subjected to known stresses of takeoffs, flying, landing, and the stresses of weather and atmosphere. The design can be subjected to these stresses via computation, as well as tested physically. The only things you can't test for are variations of manufacturing, long-term effects of random or unexpected stress, and human error in flight or maintenance. Engineers then add backup systems for critical parts, and over-engineer parts that are critical but can't have backups (like wings that support many times the load and stress that's expected during normal use). The result is that planes are the safest mode of transportation we have.
If we can design highly reliable airplanes, why can't we do the same with software?
An airplane is ludicrously simple compared to software. And a badly designed plane can't fly well, or flaws are found quickly because of inspections (or even crashes). By contrast, software is almost boundless, and errors are often hidden or even ignored. The biggest problem is that most software is based on interpretations of the real world rather than hard facts and forces like those used to design an airplane.
Software Engineering?
Software is different from engineering. The biggest problem is that we don't have equations that can be applied to help us design the pieces. We do have a collection of "cookbooks" that give the steps of a design. We also have prefabricated parts in the form of libraries. Nevertheless, if you asked 10 programmers to write a text editor, you would get 10 different designs. Yes, there are many ways to do very exacting analysis. What I'm referring to here is large pieces of softwareespecially software that has a user interface. At a certain point, complexity and human interpretation prevents exacting analysis. Compare art: How would you design software to test whether the Mona Lisa was "exact" enough?
Software Complexity or Artistic License?
Is software art? The simple answer is no, but art is a very good metaphor for how software is written. Imagine trying to duplicate our three-dimensional world with a limited palette of colors and a horsehair brush. Designing software is like that. Software attempts to capture life in a different medium of logic and graphical interfaces. Our tools are limited in their ability to be exact. Imagine trying to capture the essence of a bookstore or a factory in a painting; now imagine trying to do that with software. We can get close to duplicating some details, but there are too many; we need to make stylistic choices based on importance or need. Stylistic interpretation and techniques to catch the essence rather than the exact detail are necessary and acceptable. The design depends on the number of details, the time available to perfect the implementation, and even the interpretations of programmers, managers, users, factory workers, and the owners commissioning the software.