Holiday Party Guide to Patterns
A quick read of this holiday party guide to patterns prepares you to sprinkle your conversation with references to singletons and factories. Is someone's GUI doing a bit too much work? Let them know that your code used to be like that--until you discovered MVC. Did that fellow next to you say that he's having a hard time swapping out what type of objects are created? You chuckle knowingly that no one uses constructors in that setting anymore and suggest that he try a Factory pattern.
As with all quick start guides, you need to know when you are in over your head. If your hostess mentions an Adapter, then either she has also read this party guide or she has actually studied the Gang of Four book. For just such emergencies, you may want to hide a copy of Head First Design Patterns under the couch so that you can discretely consult it while the conversation turns back to stringing popcorn.

The Old Standbys: Singleton and Factory
OK, Singleton and Factory--you know them, you love them. Well, at the least you know of them. Who hasn't been asked to implement a singleton on the spot in a job interview, and who doesn't use some type of factory on a daily basis? Well, there's a lot more to the story, and once you've been through this holiday guide, you're going to know more than many of the developers who use these patterns. (Remember, though, we're just getting you through the party for now.)
Let's start with the Singleton pattern. It's the design pattern that ensures
only one object gets created for a given class. How? Well, in Java,
first you create a static variable to hold the reference to the single
instance and then add a static method that checks to see if the instance
has been created or not. If the instance hasn't been created, the method
instantiates one; otherwise, it just returns the instance it already has.
But this works only if everyone is a good citizen and uses your method to
get the instance; someone who isn't being a good citizen can just call
the constructor to get another instance. How can you prevent this? Just keep
your constructor private, and that way your getInstance() method
becomes the only way to create a new instance. Here's the code:

Clever but simple, right? Unfortunately, a bit too simple--what happens
in multithreaded applications? One thread could be in the middle of
creating the first instance of the singleton, when another thread comes
along and asks for one, too. In just the right circumstances, you can
end up with two instances! (Talk amongst yourselves.
We'll give you a topic: with two threads calling getInstance()
concurrently, what interleaving of operations can the allow threads to end up
with two different objects? Discuss!)

When someone starts talking about the singleton he implemented
last week, ask, "So, how are you dealing with concurrent access?"
There are actually quite a few ways people try to solve this, but most
are broken and don't work. One way that does work is to synchronize the
getInstance() method, and that is a fine solution if
your application isn't high performance.

If your fellow partier says he is synchronizing his getInstance() method,
that gives you an opportunity to dig further: "Have you considered
double-checked locking?"
Double-checked locking is a technique where you only synchronize if there isn't an instance already. This avoids the performance hit of synchronizing the entire method, but it still requires you to "double check" to make sure that two threads aren't requesting an instance the first time the object is instantiated (thus, the name "double-checked locking").
If your fellow partier with the singleton says that he's using double-checked locking, you've got one more goodie in your Christmas stocking:

This is where you ask, "Oh, did you know that doubled-checked locking is
broken in Java 2 and earlier?"
That's right--only in Java 5 is true double-checked locking possible.
The reason has to do with the caching of state information between threads
in Java. To make sure things work the way they should, you need to put
a volatile keyword in front of your uniqueInstance
variable declaration.
At this point, rest assured your peers are going to think you know
quite a bit about singletons; just make sure you do your real homework,
because you'll want to know how to use that volatile keyword and
also check out some of the other solutions to implementing correct singletons (some of which are even simpler).
Factory: Just the Facts, Jack
You've run into your share of factories, right?

A factory like RobotFactory is typically known as a static
factory. The basic idea: decouple your code from the specific type of
objects you're creating, in order to make your code more flexible and maintenance-free. As long as your factory's return type is an interface or abstract class,
you're free to instantiate any one of a number of concrete classes, and
your client code won't depend on the specific type.

Don't forget to mention that Static Factory isn't considered a full-fledged design pattern;
it's more of an idiom.
You might get raised eyebrows from your developer friends when you mention this, in fact you might even hear, "Of course Static Factory is a pattern, it's in the Gang of Four book!" If that happens, you have them right where you want them:

There are actually two factory patterns in the Gang of Four book: the
Factory Method pattern and the Abstract Factory pattern, both of them different from
Static Factory.
The Factory Method pattern is quite a bit different from Static Factory, and
uses inheritance to decouple the code that creates a concrete class.
Let's say you are coding up a simulator for Santa's workshop; you might
create a class--the workshop--that contains the code for assembling, testing, and wrapping up toys. When you write this code, you'll do it without making the workshop dependent on
actual concrete toys themselves--instead, the code depends on an
abstract method, createToy(), which is responsible for actually
instantiating the toy. Then, to create a workshop for building toy robots, you
subclass the workshop and override the createToy() method
(that is, you override the factory method), which knows how to
create robots. You can count on the workshop to handle the details of
assembling the robot, testing it, and wrapping it up. Now you need a workshop
for making Lego Mindstorms? No problem: override that createToy()
method and let the workshop code handle the rest.
The Abstract Factory is a little different--it makes families of objects. Let's say Santa wants to create his own brand of model trains, complete with the locomotive, the freight cars and the caboose, but he needs the markings on them to be regional (the Santa Claus line, the Santa Fe line, and the San Jose line). To do this you start with an abstract factory:
public abstract ModelTrainFactory {
public abstract Locomotive createLocomotive();
public abstract Car createFreightCar();
public abstract Caboose createCaboose();
}
and then implement a concrete factory for each different train line. What does that get us? Santa can write lots of code that deals with the model trains without committing his code to a particular train line. When he needs to actually instantiate train objects, he just takes a factory passed to him and can use it to create them; so, Santa's code needs to deal only with the abstract factory and doesn't have to commit to any particular implementation.
Now you know the basics of three different Factory patterns, so the next time someone brings up using the Factory pattern, you can say, "That's interesting, I love the Factory pattern! Which Factory pattern do you actually use?"
Three Ways of Wrapping Those OO Gifts: the Decorator, Adapter, and Façade Patterns
We've already given away the secret in the section title: the Decorator, Adapter, and Façade patterns all wrap other objects or classes. But to truly wrap your head around these patterns, you need to understand the subtle differences in the ways they do this. First of all, what does "wrapping an object or class" actually mean? Well, when we say an object (or class) wraps another, we just mean it is composed with that object.
Imagine you have a tree object and you want to put lights on it. You could create a light decorator object that wraps the tree:
Tree tree = new Tree(); Tree treeWithLights = new LightsDecorator(tree);
Now if you call a method on the treeWithLights, you get
new behavior. Let's say we have a method called look() that returns a
text description of the object:
Tree.look();returns "You see a tree", and
TreeWithLights.look();returns "You see a tree with blinking white lights".
That's the Decorator pattern in action: you can create objects that wrap other objects in order to provide new behavior.

If the Decorator topic comes up, just use the tree with lights
example above; this time of year, people will eat it up.

The Adapter pattern isn't any more difficult to understand: an adapter is composed with another class in order to provide a different interface. For instance, if your Christmas lights have an U.S. electrical plug and you move to the U.K., you'll need an adapter class to "adapt" your US plug to the U.K. interface.

Be sure to throw in, "An adapter wraps classes to provide a different
interface; a decorator wraps objects to add new behavior."
Façade is also a "wrapping" pattern and, like Adapter, Façade usually changes the interface of what it's wrapping, but its purpose is to make an interface easier to use. Imagine if every time you drove your car you had to manually alter the fuel intake, the amount of oxygen going into the engine, and the hundreds of other complicated things that happen as you speed down the road. Luckily, we have a great façade that consists of a pedal, a brake, and a steering wheel. That's what façades do; they stand in front of much more complex classes and provide a simpler interface.

Make sure you throw in the comment that though Decorator, Adapter, and Façade are similar in
design, they are quite different in intent. (Study the text above to make
sure you know why!)
What's a Party Without Some Gossip?
There's only one thing that's a more popular topic than design patterns at holiday parties: gossip! And we've got a doozy:

Party gossip:
Strategy and State are twins separated at birth.
You heard right. Don't believe us? Just crack open a patterns book and look up the Strategy and State patterns' class diagrams. They look pretty much the same, don't they? But how can that be? They're two different patterns, right?

Sometimes the difference between two patterns is largely their intent.
Strategy and State certainly differ in their intent. Let's break it down: the Strategy pattern is designed to encapsulate behavior, while the State pattern is (surprise, surprise) designed to encapsulate state. When we use the Strategy pattern, we create a design that allows us to change a behavior by supplying a different algorithm. For example, Santa's sleigh has several different algorithms it can use for flying depending on the expected weather on Christmas Eve (clear, snowy, and so on). If the weather changes, Santa can even change the sleigh behavior on demand.
Contrast this with the State pattern, which is designed to handle state
transitions between the possible states allowed in a system. With the
State pattern, we use objects to represent state (instead of the usual conditional statements) and we get different behaviors
depending on the state. For example Santa's sleigh has several different
states: ParkedOnRoofTop, TakingOff, Flying, and Landing. Each state reacts
differently to the same method calls; for instance, in the ParkedOnRoof state,
the unlockSeatBelt() method succeeds, while in the
Flying state, the same method call throws an
UnsafeForSantaException.

If your fellow partygoers are spitting out design pattern names like they
are big shots, just ask them about Strategy versus State. See if they can
draw the class diagrams on those cute little cocktail napkins and then
ask them how they really differ.
We're trying to make you look good, but you're actually learning something here! As you can see, it's not enough to just memorize the class diagrams; you need to understand the intent of the pattern, and some concrete examples of how a given pattern is used.
The Lowdown on MVC
Now let's talk about the big pattern: the Model-View-Controller pattern, or MVC for short. Everyone likes to talk about MVC; heck, there's even a song about it (you'll find the official lyrics in the Head First Design Patterns book).

The MVC isn't actually a pattern, it's a compound pattern. That is,
it is an OO design composed of several other patterns!
You probably know that MVC is a pattern that's often used in the design of applications with user interfaces. The MVC pattern tells us to separate any such design into three distinct systems: a Model that maintains the state of the application, a View that displays that state, and a Controller that allows the user to manipulate the state. By separating these distinct responsibilities, we create systems that are more maintainable and extensible. This design has been wildly successful; in fact, you'd be hard-pressed to find a well-designed user interface that doesn't use MVC these days, including many web applications.
The secret to MVC is that it's actually three patterns combined into one compound pattern: the Observer pattern, the Strategy pattern, and the Composite pattern. If you understand those three patterns, it makes understanding MVC a lot easier!

If the topic of MVC comes up, throw out a trivia question to the group:
"What three patterns are combined to make the MVC compound pattern?"
OK, that's even more patterns to remember for the party, but let's just get a high-level overview and they'll be easier to remember. Let's say we've got a radar system that tracks Santa on his Christmas journey. The Model is going to maintain the state of the application, storing his altitude, location, and air speed.
As those values in the Model change, we need to update the View so that we have a display that tells us accurately where Santa is located. So we make the View an observer of the Model. When you're an observer, you see everything that changes in the Model. The Observer pattern decouples the Model and the View: by making the View an observer, the Model doesn't even have to know about it, so we can add new Views at any time without changing our Model code. Now, you should really pull out Head First Design Patterns to get all of this in detail, but this should be enough to get you through the first part of an MVC discussion.
What about the Strategy pattern? The Strategy pattern encapsulates behavior. In MVC, the behavior is implemented by the Controller, because it is the component that gets the user input and decides how to interpret that input and change the state of the Model as a result. Say you want to zoom in on that graphical view of Santa's trip; you click on a zoom button and the Controller tells the Model to change its state to be more granular. But for next year, you might want to implement a sliding user-interface control that does the zoom, so you plug in a new Controller (Strategy) and you've got that functionality without affecting the implementation of the Model in any way.
That leaves the Composite pattern. To tell the truth, these days,
you probably won't have to do much with the Composite pattern yourself when
you implement MVC. Why? Because most of that work is done for you by
nifty interface builders and interface frameworks like Swing. But the
Composite pattern is there, under the covers, doing lots of work for you!
This pattern lets your program do handy things like tell the entire interface
to repaint itself, simply by calling repaint() on a top-level component. The key is that every part of a Composite--all
of the windows, the text areas, the menus, and the buttons--implement
the same composite interface. Each component is responsible for making
sure the repaint() method is called on all of the components
inside it (all of the buttons inside a window, for instance). So you,
as a programmer, just have to call repaint() on the top-level component and the rest just happens magically.

Now you know which patterns are inside the MVC, and you can even talk
about how they work! Use this to your advantage when the boss stops by your group for a little chitchat.
Party Time
Well there you go, the 2004 Design Patterns Holiday Guide! After reading this, you can't claim to be a patterns guru, but you might just look like one. But hey, you do want to be a patterns guru, don't you? Everything in this guide is just a snippet of the material in Head First Design Patterns, so make a New Year's resolution that next year, you won't be just making yourself look good; you'll be the geek leading the patterns discussion at the party. After you've read the book, you can even lead the gang in some traditional carolling:
On the twelfth day of Christmas, my true love gave to me
Twelve commands commanding,
Eleven classes façading,
Ten composites a-aggregating,
Nine iterators traversing,
Eight decorators a-decorating,
Seven states a-changing,
Six adapters a-dapting,
Five golden strategies,
Four observers listening,
Three factory patterns,
Two template methods,
and a singleton, one object, guaranteed.
And after leading the group in this carol, how far off could that raise and promotion be?
- Login or register to post comments
- Printer-friendly version
- 3734 reads



