Skip to main content

Holiday Party Guide to Patterns

December 23, 2004

{cs.r.title}








Contents
The Old Standbys: Singleton and Factory
   Factory: Just the Facts, Jack
Three Ways of Wrapping Those OO Gifts:

the Decorator, Adapter, and Façade Patterns
What's a Party Without Some Gossip?
The Lowdown on MVC
Party Time


Whether your holiday party features coffee, tea, and an assortment of cookies, or a selection of hors d'oeuvres washed down with Manhattans, you will need to be prepared to hold up your end of the conversation. Sure, world peace and what to do with all those tofurkey leftovers should hold you for a while, but inevitably talk will turn to design 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.


Presents

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:

Singleton

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!)

Party Tip

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.

Party Tip

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:

Party Tip

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?

Robot

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.

Party Tip

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:

Party Tip

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.

Party Tip

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

Adapter

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.

Party Tip

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.

Party Tip

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 Tip

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?

Party Tip

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.

Party Tip

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).

Party Tip

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!

Party Tip

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.

Party Tip

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?


width="1" height="1" border="0" alt=" " />
Elisabeth Freeman is an author, teacher and Java software developer.
Jennifer Rodoni Glore is an engineer at Sun Microsystems, Inc. Currently, she works in the Market Development Engineering Organization and helps evangelize Java technology and works on integration projects with Oracle.