I am re-reading Code Complete (Second Edition) since I read it in College. I got to the Second Chapter about the importance of metaphors and was curious what metaphor is/was most helpful to you in understanding software design/construction? I was looking for metaphors focused on Polymorphism, Inheritance, Encapsulation and Design Patterns that might be useful in helping others understand these key topics in Object Oriented Design.
I found GoF Pattern Metaphors and so far my favorite one is the Singleton Metaphor (not design pattern)
To quote the Highlander movie about a completely underlated topic, "There can be only One".
ire_and_curses post about Duck Typing
In essence, the problem is that, "if it walks like a duck and quacks like a duck", it could be a dragon doing a duck impersonation. You may not always want to let dragons into a pond, even if they can impersonate a duck.
To me, the most helpful metaphor was one you don't hear much about - information theory.
I was first exposed to this when I heard Richard Greenblatt explaining how the MacLisp system handled encoding of datatypes, such as cell pointers, atoms, integers, strings, floating point numbers, and NIL.
It's not about physical representation, it's about how choices are encoded and communicated over channels. The two main branches of information theory are 1) probabilistic (Shannon), and 2) algorithmic (Kolmogorov). They both provide different and very useful insights.
If you think about software that way, as a way of encoding information, and dealing with noise (errors), then you have a lot more choices and can make informed selections and tradeoffs.
Typically I try not to think too hard about metaphors; the problem itself is what I'm concerned with. If an object is in the problem space, then I write it out as part of the solution.
When doing inheritance-y things, I inherit due to a shared and abstractable quality inherent in both of the objects that can be factored out.
Helios points out that shared qualities can also be factored into a common object; the has-a relationship. My reply mentioned the is-a relationship.
Define the word "chair". I like to use this as a starting point to explaining the concept of abstraction. First, it can be used to make clear that, while all chairs share some common features (whatever those may be), there is no chair, that is just a chair (each specific chair is different from all other chairs in some respect). Also, it shows how difficult it can be to make concepts in your head explicit.
I would say any use of metaphors was counter-productive for me to understand and learn object oriented design as I know it now correctly. It may be helpful to explain something technical to a layperson but when you have trouble explaining it to a peer without metaphors chances are you don't understand it thoroughly.
It is more profound and helpful than polymorphism, inheritance, encapsulation and all others. OO design patterns can guide beginners to avoid worst coding, but only succinctness can lead one to perfection.
Electronics.
As someone who started out in electronic engineering and moved into software, I find that there are many useful analogies that can be made between electronic design and software design. (Components, circuits, interfaces, networks, etc.)
It also goes beyond design. Electronics is a more mature engineering discipline, and a lot of the processes and techniques that one uses in electronics can also be applied to software engineering.
Learn from the lessons from GoF Design Patterns: Program to an 'interface', not an 'implementation'. Favor 'object composition' over 'class inheritance'.
And test first.
The most useful metaphor for me has been thinking of objects not as things that can be manipulated, but as people that talk to other people or send messages to other people.
Cars. Everybody understands how to use them but few understand how they work. So it's a great metaphor when I need to explain a componentized system with an interface. And almost anything can be described in car terms.
For example, got a coworker who doesn't write unit tests? You've got a mechanic who doesn't start the engine after changing the oil.
Need to explain why putting that button on the screen will take 3 days? Tell them that you need to disassemble the dashboard and install a fuse panel. When they tell you don't worry about the fuse panel, ask if they'd drive their car around with a nail where a fuse belongs.
Finally, Charles Petzold is always very good at metaphors. I liked his Paul Revere story in Code.
I really like the "encapsulate what varies" mantra of the Head First Design Patterns book, and specifically, the use of the programmable remote control metaphor for the Command pattern.
The Client (lazy couch potato dad) creates the Command object (programs the remote control). Then the Client (dad) can use the Invoker (press the remote button) to invoke commands against the Receiver (the thing the remote control is controlling).
When I taught undergraduates Java, I have found taxonomy (plant kingdom, animal kingdom, through mammals, to species) to be useful.
- Most kids already know about evolution and so the idea of "inheritance" strikes a metaphorical chord.
- Class vs object is as simple as "cat" vs "Tiddles"
- Abstract classes are obvious -- there is no instantiating "animal", only (say) "ant" or "monkey" (ever met an animal that belonged to no species?)
- Interfaces also become obvious -- both whales and fish like to swim
- Encapsulation is again fairly obvious (try touching that animal's spleen without a scalpel)
- Polymorphism based on inheritance is fairly obvious (what does it mean for a slug vs a human to eat a piece of lettuce?)
- Polymorphism based on method overloading is fairly obvious (kill a lion vs kill a bacterium)
- You can start talking about more advanced topics -- cats without tails; sea-squirts that are vertebrates to begin with but not later; men in gorilla suits, duck typing, etc.
You can stretch that metaphor a very long way.
For design patterns, it's usually easier to pick human situations, as the "design" part of it is key -- not just "what's it mean" but "why might I decide to use that pattern"
- observer (publish/subscribe) fits well with real-life publish/subscribe (Reader's Digest etc)
- there are lots of human-specified Singletons ("the UN", "the Vatican", etc)
- IIRC, MVC was first described with it's own old-time real-world metaphor (punchcards, computers, and print-outs)
- Monopoly Chance cards (or Magic the Gathering cards) work well for Command pattern
- Factory speaks for itself!
So it's not that there's a key metaphor for design patterns, but it's not hard to spot real-life equivalents of them.
Scheme's Continuation-passing style
it may not seem as a metaphor at first, but once you've mastered one:
- preserving state in endless recursion
- multiple argumnets, some of them executable
- multiple return values, some of them executable
- being aware of what is data and what is control
then you realize that all petterns and metaphors are specific cases of CPS...
Say you're in the kitchen in front of the refrigerator, thinking about a sandwich. You take a continuation right there and stick it in your pocket. Then you get some turkey and bread out of the refrigerator and make yourself a sandwich, which is now sitting on the counter. You invoke the continuation in your pocket, and you find yourself standing in front of the refrigerator again, thinking about a sandwich. But fortunately, there's a sandwich on the counter, and all the materials used to make it are gone. So you eat it. :-)`
Sorry I’m joining the thread late. I just stumbled upon it. I developed a Design Pattern course at my company, and I used a lot of metaphors.
Inheritance –
Animal classification. Vertebrates, Mammals, Sponges, Insects, etc. are all examples of classes where traits reside at different levels. For example, all Vertebrates have a spine. Insects have six legs, etc.
Vehicles. A vehicle can be land, sea or air based. Each of these can be split further, car, truck, boat, ship, submarine, airplane, helicopter, etc.
Encapsulation – The motor of a car is encapsulated from the driver. It is literally “under the hood.” I operate my car via the key/ignition, steering wheel, gas and brake petals. I don’t have to know nor worry about the specifics of an internal combustion engine (or hybrid engine for that matter).
Polymorphism – Back to animals. Every animal needs to eat, but they all eat in different ways specific to themselves. Some are herbivores, carnivores or omnivores. Some are filter feeders. They all eat, but the eating technique is unique to many of them.
Interface (not in your list) – I’m adding it, because Interface is an important OO topic, especially since it’s a specific concept in Java and maybe other languages as well. My accountant prepares taxes. H&R Block employees prepare taxes. Some lawyers prepare taxes. “Tax Preparer” could be an interface. It defines what is performed, but it has not part in declaring how it is performed. Accountants, H&R Block employees and lawyers can all declare themselves as tax preparers, and they may all three use completely different techniques to prepare taxes.
Delegation (not on your list) – Delegation (AKA collaboration) appears repeatedly in the GoF book. Let’s go back to tax preparation. An accountant may declare himself as a tax preparer, but he may delegate the work to a junior member, who may delegate it to TurboTax.
Design Patterns – They are techniques that work will in OO environments. I compare them to data structures, which are techniques that work well in procedural environments. Just like data structures are mostly based upon pointer manipulation, design patterns are based upon inheritance, encapsulation, polymorphism, etc.
It’s like Tex-Mex food. There are only a few basic ingredients: tortilla, beans, meat and cheese. Wrap it, it’s a burrito. Bake it, enchilada, Grill it, quesadilla, etc. Design Patterns are almost like recipes. Once you master the basic OO skills, you can learn to combine them using the design pattern “recipes”. Once you master the design pattern, you can begin to experiment with it, just as a chef would.
A cook is someone who knows how to create a dish. A chef is someone who knows why the dish works. Learning design patterns can help move you from software cook to software chef.
I used a metaphor for each pattern I presented. Here are a few examples:
- Object Pool (not in the GoF) – Bowling Shoe Rentals
- Prototype – Jango Fett and the Clone Troopers from Star Wars
- Adapters – Electrical adapters for international travelers
- Decorator – A factory assembly line
- Proxy – An ambassador
- Command – Star Trek with Kirk giving the “All hands report to your battle stations”. It’s a different task for each member of the crew triggered by the same order.
- Template Method – Happy Meal
- Chain of Responsibility – Calling customer support and asking to speak to a supervisor when you don’t get the results you desire. The judicial system of taking a case to a higher court.
- Observer – A radio station broadcasting its programming. A lifeguard on duty.
- Visitor – A work office where various visitors could come to you: window washers or ISO auditors. Each performs a different task, but the would need to be signed in, and possibly escorted.