







 |
|
 |
Creational Patterns in Everyday Life
Niranjan Ramakrishnan
Among object-oriented design patterns, creational patterns are
especially interesting. They strike at the very root of the problem -
how to generate an instance of the class. The Gang of Four
book discusses five creational patterns:
A creational pattern can be any standard way in which an instance
gets created. The key questions in creating an instance
are as follows:
- How will derived class instances of this class whose instance
I am creating be created in the future?
- Is there a way in which I can specify less than I
am via this current mechanism?
- Is there an easy way to vary the parameters of
creation?
Good creational patterns try to provide reasonable
answers to these questions. Here are creational patterns from
the Gang of Four book and examples of such patterns
from real life.
Abstract Factory
An abstract factory allows me to refer generally to a creation mechanism
within my code, and not change anything within my code except
the way the class of the creational mechanism itself. Very
often my code does not even need to be aware of which variant of the
abstract factory is being used - the right thing happens. The example
in the GOF book uses a GUI abstract factory - the actual instance of the
factory could be a Motif Factory or a Presentation Manager
factory. The methods in the abstract factory are, naturally,
all abstract - createMenu() would result in the creation of a
Motif menu if the factory were a Motif Factory,
or a PM menu if the factory were a Presentation Manager.
There are many examples of abstract factory in the
real world. A business traveler travels to a new city.
Landing at the airport, the traveler locates the car
rental terminal, rents a car. The car rental place has
a way to reach a renter to the car. This is a general scenario,
which is re-applied each time the traveler goes to a city,
but with its own context - some airports have rental
offices in a different building, some airports have
buses to take renters to the car lot, while other rental
agencies have attendants who bring the car to the renter. In any
case, the renter deals with the general notions of an Airport,
Car Rental, etc.
Factory Method
When I first came across the Abstract Factory and the
Factory Method design patterns, I was often confused by
their similarity. Eventually I began to discern their key difference.
The Abstract Factory is where the client deals
with the object (or instance) of a derived factory class. Factory Method,
on the other hand, is where the client deals directly with the
class of the factory itself. The differences in the two arise
primarily from this. When you are dealing with an instance, you can be
polymorphic. When you are aware of a class, it is more
difficult.
In the Factory Method, the class has various
static methods, which return a base class reference to
an appropriately created derived class object. The cleint
is aware of the class (which it uses to create the
various component instances).
Examples of the Factory Method in real life are also
common. The Factory Method implies a pre-fabrication at
the factory level.
So, when our traverer gets out of the airport parking lot
and feels hungry, he stops at a restaurant. Here, he
finds several "Build your own dinner" packages, each of which is a specialized
combination of a salad, a soup, an entree and a dessert.
The restaurant has constituted a number of standard and
popular offerings into "classes", which can be
instantiated as governing entities. Being a vegetarian, the
patron tells the waiter to bring him a Vegetarian salad,
a Vegetarian entree, a Vegetarian appetizer, etc.
Here are the differences between Abstract Factory and
Factory Method in brief:
| Abstract Factory |
Factory Method |
| Client asks instance for a suitable component |
Client asks class for a suitable component |
| Client keeps reference to factory instance, calls it to obtain components |
Client uses class, calls methods to create compatible components |
| Client deals with a group of classes at a level of total generality |
Client deals with a group of classes at a less general level |
Builder
The Builder pattern allows clients to be oblivious of the
components of a design. The builder is like an Abstract Factory
in that clients deal with a base class reference which actually
ends up referring to a derived class instance. It parts company with
the Abstract Factory in that the client does not
go asking the factory to produce individual components. The builder
produces them. The client is shielded from the details.
As with the Factory Method, the Builder implies
pre-fabrication, but this pre-fabrication is of the product, not
the factory.
As an example of the Builder pattern, consider a
situation where is where the traveler chooses from one of
several pre-designed packages at the travel agency -
everything is pre-packaged, the entire combination is
purchased. Or, when the restaurant has several advertised
"specials", which provide various standard meal options.
The word Builder is somewhat misleading for this pattern,
at least looking at it from the client's angle. The client does
not get to build things here, certainly there is far
less control on the part of the client here than in the
two factory patterns.
The Builder is also to be encountered in the bundling
of computer, printer and scanner often sold as a package
in computer stores. They are not sold separately, and
anyone who buys them has very little choice of customization.
The benefit? Simplicity. The drawback? Rigidity.
Prototype
The Prototype is as its name suggests. The creation of a
prototype is akin to choosing from a set of model homes. Builders
(home builders, not the pattern!) often complete a set of
sample homes, which potential homebuyers can look at. Once a
homebuyer picks out a home he or she likes, the home-builder can quickly
construct a replica at a given site.
The Prototype relates to Builder as the
Abstract Factory relates to the Factory Method. In each
case, the former technique relies on the client picking (or
being supplied, more likely) a particular generator instance, which
then takes care of generating the instance the client
requires.
The Prototype differs from Abstract Factory in
the fact that it produces a fait accompli, the
client gets the whole instance rather than an instance
which serves as a factory (although it certainly could be
used in this way).
Restaurants in Japan are famous for displaying the
main dishes of the day, as they would be served, on the
front window. Even those who do not know Japanese can
take the waiter to the window and point out what they
want. This is the Prototype pattern at its
finest!
Singleton
The Singleton is also as its name suggests -
a unique instance. The pattern enables the creation
of one instance of a class, but no more. All clients
share the same instance of the class.
If the client tries to create more than one instance,
it can be given back the single instance that
already exists. If no instance exists as yet, it
can be created.
The Singleton is one of the most common patterns
in real life. To continue the resturant analogy.
Every morning, the restaurant prepares a fresh pot of
coffee. When customers ask for coffee, they are given
a cup from the pot. When the pot runs out, it is
refilled. But the point is, coffee is not freshly
prepared for each customer (all right, I admit it, we are
not talking about a fancy coffee boutique, OK?), but is
instead managed from a single instance.
The other instance of the singleton object is both
glorious and tragic. Shah Jehan, the Indian king who
built the Taj Mahal for his dead queen, cut off the
thumbs of all the stonemasons who worked on the marvel,
so that they would never again build a similar monument
for anyone else.
Which Creational Pattern to use?
Each creational pattern has its own strengths and weaknesses, which are summarized in the table
below. It is also true, as has been pointed out in the
Gang of Four book, that one creational pattern may well
be implemented using another one.
|
Abstract Factory |
Factory Method |
Builder |
Prototype |
Singleton |
| When to use |
Need complete flexibility - new kinds of
derived classes could be created later which would be
usable by the client |
Need limited flexibility - choose from among
a limited set of configurations |
Don't want the details, want a configuration
which will enable me to start working on it right
away |
Don't want the details, don't even want to
pick what package I will get - it will probably
be passed to me |
Want to create only one of these - could be known
to me, or could be passed to me |
| Client knowledge |
Less knowledge of type - client knows base type, not specific class.
Knowledge of class flexible, but knowledge of
elements of the configuration, it has to create
them explicitly |
More knowledge - client knows specific type, and
knows about the internal configuration - it has to create
them explicitly |
Less knowledge of details, no knowledge of
configuration |
More knowledge of details, some knowledge of
configuration - enough to make the right choice |
Orthogonal to how much client has to know, but
knowledge limited by the fact that most of the time, it
uses an instance that already exists |
| Advantages/ Disadvantages |
Great flexibility, Low client knowledge |
Reduced flexibility, High client knowledge |
Reduced flexibility, minimal client knowledge |
Good flexibility, minimal client knowledge |
Variable flexibility, minimal client knowledge |
Top
Journal Archives | Send Feedback
CopyrightÓ
Pantheon Systems, Inc. All rights reserved.
|
|