Don't believe anything you read on the net. Except this. Well, including this, I suppose.
I'm writing this on March 11, 2013, what would have been Douglas Adams' sixty-first birthday. If you do not know who Douglas Adams is, or you recognize the name but never read anything that he has written, you have robbed yourself of one of the greatest reading pleasures known to man or little furry creatures from Alpha Centauri. Adams died way before his time in 2001, but while he was alive he shared numerous, unintentional pearls of wisdom about software development and knowledge work that are as relevant and chuckle inducing today as they were when he wrote them. For example: I really didn't foresee the Internet. But then, neither did the computer industry. Not that that tells us very much of course—the computer industry didn't even foresee that the century was going to end.
In honor of what would have been Adams’ sixty-first birthday, here are some of those nuggets and my take on what they mean today.
Software Development Is about Solving Problems
A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools. (Mostly Harmless)
What Adams refers to here is really a quest to help solve problems that people and organizations face and a subtle warning to not get too wrapped up in trying to provide the perfect solution. A good solution sooner is much better than a nearly, but not quite, perfect solution later. Don't let a quest for perfection, which you may never reach, prevent you from sufficiently solving your shareholder's problems now.
Software Development Is about Solving the Right Problems
I have a well-deserved reputation for being something of a gadget freak, and am rarely happier than when spending an entire day programming my computer to perform automatically a task that would otherwise take me a good ten seconds to do by hand. (Last Chance to See)
Many of us got into software development because we enjoy solving challenging problems and because we like tinkering. But to be truly effective, you must know which problems are the right ones to solve. You can't answer this alone. It's best to work with your stakeholders to come to a common agreement as to what the problem is and why it is worth solving.
Many stakeholders don't take this perspective. They often run into a problem and cook up some solution based on what they have seen work in some other context. You may get some resistance when you try to get the stakeholder to step back and explain the real problem they are trying to solve and let you provide options, but it is really in their best interest. More often than not, once you understand the true problem, you'll be able to provide a simpler solution, quicker, than had you just done what the stakeholder initially asked you to do.
The major difference between a thing that might go wrong and a thing that cannot possibly go wrong is that when a thing that cannot possibly go wrong goes wrong it usually turns out to be impossible to get at or repair.
I see this quite a bit working on enterprise-driven software development efforts, where the software is built for use inside an organization. One group of people develops the solution and then hands it off to a different group of people to maintain going forward. If the first group doesn't produce well-crafted code, the people who have to support it find that they spend a lot of time trying to find and fix those things that couldn't have possibly gone wrong, but did.
There's a couple ways of addressing this. One way is to have the people who initially develop the solution actually support it. I realize there are all kinds of arguments for why this won't work, many of which are artificial constraints based on bad assumptions of how software development organizations should work. The second way, and probably something you should do regardless of whether you chose to do the first or not, is to build software so that it is easy to maintain, which often means making it as simple as possible and not trying to have it do too much.
Software Development Is a Knowledge-Generation Activity
What I mean is that if you really want to understand something, the best way is to try and explain it to someone else. That forces you to sort it out in your own mind. And the more slow and dim-witted your pupil, the more you have to break things down into more and more simple ideas. And that’s really the essence of programming. By the time you’ve sorted out a complicated idea into little steps that even a stupid machine can deal with, you’ve certainly learned something about it yourself. The teacher usually learns more than the pupil. Isn’t that true? (Dirk Gently's Holistic Detective Agency)
You may assume that the acts of analysis and design, when done properly, generate all the knowledge you need to develop the code that solves the given problem. Analysis and design do generate knowledge, but the learning does not stop there. In fact, the point where you know the most about the problem and possible solutions is after you have developed one or more solution. Understanding that will make it easier for you to not rely solely on analysis and design and instead look for ways that you can take advantage of the knowledge generation that occurs during development to help determine the best course of action. This is a strength of iterative development. Don't know how to solve a particular problem? Start down a path you think might work, and before you go too far, show it to your stakeholders to see if it is the right path. Based on that feedback, adjust accordingly. It's better to accept that you don't know everything when you start development and take advantage of the information you uncover than to lock in on a particular solution and be surprised when you discover something else would work better.
We Learn Best from Failure, usually Our Own
“A learning experience is one of those things that says, 'You know that thing you just did? Don't do that. ’” (The Salmon of Doubt)
Just like the act of writing code is a knowledge-generation activity, the entire software development process offers many opportunities for learning. I have picked up some good information from my successes but, more often than not, I was successful on those occasions because I had learned from my failures. No one likes to fail, but if you can keep your failures small and immediately figure out what you can learn from them, the failures don't sting quite as much. That's the idea behind a delivery team holding retrospectives during the course of its effort. If team members pause frequently and discuss things they have learned with an eye toward continuing to do the things that worked and changing the things that didn't, the delivery team on the whole will be much more effective.
Contrast that with the dubious value of reviewing lessons learned at the end of projects. In those cases, team members who are weary from the project that just ended and just want to move on to something else, get together to gripe about or blame each other for things that didn’t go well. They may come up with some advice for future project teams, but they generally don’t put much effort into it, because it's too late to help them. The results of these discussions, if recorded, are rarely referred back to and the knowledge gained recedes into history. Adams nailed this aspect of human behavior in his book Last Chance to See: “Human beings, who are almost unique in having the ability to learn from the experience of others, are also remarkable for their apparent disinclination to do so.”
It took me a while to realize that if I really want to avoid the big nasty failures, I should put myself in situations where I can have small recoverable ones from which I can learn, and that I should listen to those with more experience.
What’s the Point?
There was a point to this story, but it has temporarily escaped the chronicler's mind. ( So Long, and Thanks for All the Fish
Actually, I do remember the point. I can be fairly certain that Douglas Adams did not write these excerpts with various lessons about software development in mind (OK, a couple he probably did), and it is possible to find quotes to support just about any perspective if you try hard enough. What I'm trying to convey here is that software development has a substantial human element to it—whether it is understanding the problem you are trying to solve, making sure it's the right problem, or learning from your efforts to solve that problem.
Douglas Adams passed away before many in the industry really began to realize that the human element in software development was important, but had he lived, I imagine he would have had a lot to say on the subject and the conversation would have been richer because of it.