Patterns with Everyday Examples
Niranjan Ramakrishnan
Why are object oriented design patterns
are different from, say classes and methods?
In a sense, classes and methods are more
useful, as they allow a concrete and quantifiable mechanism for reuse.
Design patterns, on the other hand, do not provide a one-time implementation
which can be reused ad infinitum. Instead, they provide a high-level
indication of a solution to a particular kind of problem. Whether this
makes for more or less reuse and at what level, we shall leave to the philosophers
to debate. For our purpose, what they offer is an easily remembered plan
of attack.
Reuse of classes is wonderful when it happens,
but is impossible to achieve in many cases. This is because the classes
were written for a different context, and cannot be used as such
in a different context. Inheritance, though often touted as a cure for
such situations, is easier said than done for well-established classes,
and even if possible, is fraught with other problems. In such cases, design
patterns are the answer. They provide us signposts on how to attack a problem
applying previous knowledge, rather than making us wait for the for an
appropriate problem.
The more such knowledge becomes blended
into the designer's thinking, the more supple and insightful the designer's
approach gets. It is a chore to look up suitable books and references to
come up with suitable patterns, though. For the basic level at least, designers
need to remember the patterns easily. This is well accomplished by using
one of the patterns themselves (the prototype, or exemplar) to remember
what a pattern stands for. In this article we try to provide simple examples,
which, even without code, will be something designers can remember and
use.
Take the case of object creation. The design
patterns book lists five common patterns of object creation.
-
Abstract Factory
-
Factory Method
-
Singleton
-
Prototype
-
Builder
In this article, we take the first two,
explain their purpose, and give an everyday example of its application.
In the next article we shall explore the other three, and summarize
the creational patterns as a whole.
Abstract Factory
The problem
When a client wants to write general-purpose
code (read: almost always) environmental references are an impediment.
Code peppered with references unique to the current environment can result
in great difficulty when the code is called upon to work in other environments.
The solution
Refer in the code to general facilities
offered by the environment and make the environment an abstract class offering
these facilities. Then, each specific environment can be made a derived
concrete class of the base class environment, redefining creation
of the facilities listed in the base class in a suitable fashion.
The specific environment object is instantiated once and subsequently used
by the client. It can be replaced by another environment object without
any change to the client. Also, the derived classes return objects
that are internally consistent and will work within the context of that
derived class.
An Everyday Example
Take the example of a Car. There
are part books which contain sections of pages for each car model.
Each section has a standard list, providing part numbers for the various
spare parts for that model, such as engines, tires, transmissions, brakes,
etc. Once you provide the car model, the spare part information is generated
with no further input from you. Thus, clients only have to refer
to an abstract Car, and the concrete version of the car which they actually
refer to yields the appropriate spares.
Factory Method
The problem
Encapsulation. We want to create
an object which will then take care of creating all the appropriate objects
inside it. We don't want to be involved in each object's creation.
The solution
Create a similar hierarchy to the Abstract
Factory hierarchy. However, see that the factory has methods to return
various kinds of derived classes, so that clients do not have to be bothered
with the chore of creating them.
The Everyday Example
Travel companies offer different kinds
of vacation packages. Clients can choose from the travel company which
vacation package they are interested in. The various elements of
the package are pre-built to be internally consistent - your flights are
coordinated with your car rentals, your hotel is coordinated with your
itinerary, etc. Thus,
class Vacation {
static Vacation HawaiianVacation(double budget) {
}
static Vacation CaliforniaWineCountryVacation(double budget)
{
}
static Vacation CivilWarSitesVacation(double budget) {
}
//...
int duration() {...}
int vacationClass() {...}
boolean changesAllowed() {...}
//etc...
}
Underlying these, perhaps,
are derived classes HawaiianVacation, CaliforniaWineCountryVacation,
CivilWarSitesVacation, etc., but the
client
never has to see them. The interfaces
to the base class is all the client has to see.
Top
Journal Archives | Send Feedback
CopyrightÓ
Pantheon Systems, Inc. All rights reserved.
|