Frameworks are Mad Libs
I realized yesterday that a great way to explain how frameworks work, and how they are different from code libraries, is to compare them to a Mad Lib. This metaphor isn’t for computer science types, but for “lay people” like my mom. Until now, I hadn’t come up with an example of something in the real world that acts like a framework, where the skeleton is separate and you fill in parts.
For those who don’t know what a Mad Lib is, you can see them in action on this site. Basically, it’s a sentence that’s missing some parts. You supply the parts, like “a person’s name”, “an adverb”, “a food”, or “a place to eat dinner”. In a Mad Lib, these parts are placed into a sentence you haven’t seen yet, and hilarity ensues:
George was sexy hungry, so he ate his turnip salad on Mt. Everest.
The incomplete sentence is the framework, and the additional words are the new part of the program you would write to extend the framework. Of course Mad Libs are funny because you don’t know the sentence in advance, but extending a framework is hard in the same way because your knowledge of the framework is imperfect and that leads to bugs.
This metaphor makes one characteristic of frameworks clear: The framework owns the skeleton of the application. By adding your words, you can complete the sentence, but you can’t take the sentence somewhere else. In the above example, you can’t turn it into a discussion on human rights. Ok, maybe you can shoehorn or “hack” it into political commentary:
The prisoner at Guantanamo being held in violation of Habeas Corpus was not fed for a week so he was very hungry, so he ate his mattress from his 6x6 foot cell salad on advice from the Red Cross.
But clearly it’s not the kind of sentence you’d write if you had control over the skeleton, which here is owned by the framework.
When frameworks were first described, they were presented as incomplete solutions to problems, much like this Mad Lib sentence. That is, the sentence makes no sense until you add the missing parts. People talked about “instantiating” the framework. Modern frameworks often stand alone, but also allow you to add parts. Continuing the metaphor, it’s like the parts are independent clauses (or some other sentence part that I should have learned in high school). The sentence might be: The web server served pages. That makes sense by itself, but we can extend it this way: The concurrent, caching, SSL_web server served _banking pages. It’s a sentence that still provides a skeleton and extension options, but it’s standalone.
So if frameworks are Mad Libs, what is my research on Design Fragments? While Mad Libs are a game to make funny sentences, engineers use frameworks to build useful things. Engineers don’t mind repeating themselves and being boring so long as it gets the job done (this is true perhaps beyond the domain of Mad Libs). Design Fragments describe known-good ways to fill in the Mad Lib so that it “works”, i.e., it’s grammatical. My empirical study found that once engineers discover a way to fill in the framework, they copy that solution over and over. Design Fragments are a kind of recipe describing how to fill in the framework successfully that can be checked by the computer to ensure the recipe has been followed.
For those of you familiar with design patterns, you’ll see Mad Libs as very similar to the template pattern, where an abstract algorithm is described in a superclass and whose particulars are completed in a subclass. (Please ignore the subclassing mechanics of the template pattern – the important part is the intent). With the template pattern, you have to fit into an incompletely specified algorithm dictated by the superclass, and so you have an obligation to somehow complete your part, and observe some (usually unwritten) contract or constraints. Note that in the Mad Lib, if you give it a noun when it asks for an adverb, the resulting sentence just won’t make sense.
You can implement a framework many ways, including using the observer pattern, or using function pointers. Note the difference in intent between the template method and observer/function pointers. With the template pattern, you have to fit into an incompletely specified algorithm dictated by the superclass, and so you have an obligation to somehow complete your part, and observe some (usually unwritten) contract or constraints. With the observer pattern (or raw function pointers), the model notifies observers that a state change has happened but should not expect them to do anything, i.e. there’s no contract. Put another way, the model in the observer pattern should never break if an observer fails to do something, while the abstract algorithm part will usually break if the plugged in part doesn’t do what it is supposed to.
I believe that most framework hot spots really have contracts associated with them, more like the template pattern. My bias is that I think frameworks often pretend that the hotspots have no contracts, but usually they have hidden contracts.