I have come up with an analogy that should make the basic principles of software design understandable to everybody. The great thing about this analogy is that it covers basically everything there is to know about software design.
Imagine that you are building a structure out of lead bars. The final structure will look like this:
| _|_|_|_ | | |
You have to build the structure and put it up at a certain location, so that people can use it (for this example, we don’t care what they need it for, but assume that they need it for some specific reason).
The lead bars represent the individual pieces of your software. Putting it up at the location is like putting your software into production (or sending it out to your users). Everything else should be fairly clear as to how it translates to software, if you think about it. You don’t have to translate everything to software in your mind as you read, though. Everything should be quite clear if you just imagine that you really are just building a structure out of lead bars.
The Wrong Way
Imagine that you were building this all by yourself, and that you had to make the bars out of raw metal. Here’s the wrong way to build it:
- Make one tall lead bar, and lay it flat on the ground in your workshop:
| | | | |
- Cut a hole through the tall bar, and measure that hole.
- Make a new bar that will fit through that hole:
- Put that new bar through the hole and weld them together permanently:
| __|__ | | |
- Cut two holes in the horizontal bar, measure them, and make two new lead bars that will fit in those individual holes:
- Insert the two bars into the horizontal bar, and weld them together permanently:
| _|_|_|_ | | |
- With a forklift, put this into a truck to move it to the location where it’s supposed to be (It’s too heavy to move by yourself.)
- With a pulley, make the construction stand upright and put it into the ground.
- Discover that it won’t stay up by itself, but if you put some blocks next to it as an emergency solution, it doesn’t fall over:
| _|_|_|_ | _|_ | | |
- Three days later, watch the structure fall over and break because the blocks aren’t actually a permanent solution.
- Unfortunately, part of the horizontal bar has snapped, and you have to fix it. This is difficult because the bars are all welded together, so you can’t easily take out the bar and replace it with another one. You either have to build a whole new structure or weld together the broken bar. Welding the broken halves together creates a weak bond, but it’s cheaper than building a whole new structure, so you just weld them.
- Put stronger blocks next to the structure to keep it up.
- Next week, the weather breaks the welded bars. Weld them back together again.
- In six days, watch the structure fall over because blocks are not a permanent solution.
- Repeat the last few steps until you run out of money or time.
Analysis of The Wrong Way
So, what was good about the above process? Well, it did allow one person to successfully complete a structure. In software terms, that one person “made something that works.” It also created a lot of work for one person, which is good if that one person wanted a lot of work.
What was bad about it?
- The bars all had to be made in sequence, individually.
- Problems with the final structure (that it wouldn’t stay up) were only discovered after it was entirely built and in place.
- When problems were discovered, they were just “quick fixed” without planning for the future.
- It took enormous effort to move the completed structure into place.
- If we ever had to change the configuration of the bars, we couldn’t, because they’re welded together. We’d have to build a whole new structure.
- The completed structure requires frequent attention.
And I’m sure we could come up with other faults. This whole analogy (including the parts below) could be analyzed all day.
Bringing It To a Group
The biggest problem with the Wrong Way process is that it wouldn’t work at all if there were multiple people working on the project (as there usually are in real-world software projects). The main problem is that you had to measure all the holes before you built a bar, so everything had to be done by one person, in order.
There are, generally, two ways to solve this problem:
- Write a specification for the sizes of all the individual holes beforehand, and then spread out the work of making all the different bars for each hole.
This is problematic because one person has to write this specification, and if this were a large project (imagine thousands of holes instead of just three or four), it would take a lot of time. Nobody else on the team can be working until the specification is completed. The spec could be full of mistakes–there are as many chances for mistakes as there are holes specified, so if there are thousands of holes, that’s a lot of chances for errors to be made.
- Just say, “All bar holes will always be the same size and in the same places on the bars. Bars can be screwed together.” Then set everybody to making bars with standardized holes (or go buy them from the store).
That is simple, and it gets everybody working at once. Because you’ve standardized your bars, you’ve lost a little flexibility in dealing with any special cases that come up (maybe a half-width hole would be more useful in some part of the structure). However, you should be able to build a decent structure entirely with standard holes, so that’s not too much of a problem. And when you have a standard, you can make specific exceptions in some places more easily than if things are not standardized.
Of course, with this method it is very important that you do a little research to pick a good hole size and good bars.
The Right Way
So, what would our process look like for many people all using standardized bars that screw together? (This is the right way to build something.)
- Have your team all go build (or buy) their individual bars. You can have as many people working simultaneously as there are bars in the structure.
- Have them test their individual bars to make sure that they won’t break.
- Have them carry their individual bars to the place where the structure needs to be.
- Put the first bar into the ground, standing upright:
- Push on the first bar from all angles to see if it is going to fall over.
- Screw in a second bar to the first one:
- Test the complete structure now, only to find that it’s not strong enough to stand by itself.
- Attach unbreakable steel ropes to the sides of the structure, like so:
/|\ / | \
These ropes should be able to withstand anything within reason, or even well beyond reason.
- Test it again and find out that it now can stay up no matter how hard you push on it.
- Add a third bar, and put new ropes on so that it looks like this:
/|\ //|\\ // | \\
- Remove the lower ropes:
/|\ / | \ / | \
(Anybody who’s been involved in refactoring Bugzilla can remember doing a lot of things that sound just like these last two steps. 🙂 )
- Test it again.
- Continue these steps until you have a completed structure:
| _|_|_|_ / | \ / | \ / | \
- When a pipe breaks in three months, figure out what was wrong with that pipe, fix the problem, and replace it with a new pipe that fits into the same holes. The structure is just as strong as it was before.
- Continue the above process until you no longer have to pay attention to the structure and it just stays up all by itself.
- Adjust the structure as necessary for the changing requirements of the users of the structure, which is easy because the holes are all standardized.
So, did you notice that we followed all the Laws Of Software Design?
- We thought about the future. We did that for the entire process, but we particularly did it when we put on unbreakable steel ropes that would last no matter what happened in the future.
Also note that we didn’t try to predict the future, we just followed our principles so that no matter what happened, our structure was going to stay together and be easy to build.
- We allowed for change by screwing the bars together instead of welding them. We also put standardized holes in all the bars, even if we didn’t need them, in case we needed to add more bars in the future.
- In every step of creating the structure, we kept our changes small and tested everything as we went. Creating each individual bar was a small task, and we put them together in small steps.
- And of course, the most important decision we made was to keep it simple by making all the holes consistent and standard, and keeping each piece small and simple.
Whether you are one person or a thousand, whether your project is 10 lines of code or 10 million, this process will work.