Design Patterns: Elements of Reusable Object-Oriented Software
153
Discussion of Creational Patterns
There are two common ways to parameterize a system by the classes ofobjects it
creates. One way is to subclass the class that creates theobjects; this corresponds
to using the Factory Method (121) pattern. The main drawback of thisapproach is
that it can require creating a new subclass just to changethe class of the product.
Such changes can cascade. For example,when the product creator is itself created
by a factory method, thenyou have to override its creator as well.
The other way to parameterize a system relies more on objectcomposition: Define
an object that's responsible for knowing the classof the
product objects, and
make it a parameter of the system. Thisis a key aspect of the Abstract Factory
(99),Builder (110), and Prototype (133) patterns. All three involve creating a
new "factory object" whoseresponsibility is to create product objects. Abstract
Factory has thefactory object producing objects of several classes. Builder has
thefactory object building a complex product incrementally using acorrespondingly
complex protocol. Prototype has the factory objectbuilding a product by copying
a prototype object. In this case, thefactory object and the prototype are the
same object, because theprototype is responsible for returning the product.
Consider the drawing editor framework described in the Prototypepattern. There
are several ways to parameterize a GraphicTool by theclass of product:
•
By applying the Factory Method pattern, a subclass of GraphicTool will
becreated for each subclass of Graphic in the palette. GraphicTool willhave
a NewGraphic operation that each GraphicTool subclass willredefine.
•
By applying the Abstract Factory pattern, there will be a class hierarchyof
GraphicsFactories, one for each Graphic subclass. Each factorycreates just
one product in this case: CircleFactory will createCircles, LineFactory
will create Lines, and so on. A GraphicTool willbe parameterized with a
factory for creating the appropriate kind ofGraphics.
•
By applying the Prototype pattern, each subclass of Graphics willimplement
the Clone operation, and a GraphicTool will be parameterizedwith a prototype
of the Graphic it creates.
Which pattern is best depends on many factors. In our drawing editorframework,
the Factory Method pattern is easiest to use at first.It's easy to define a new
subclass of GraphicTool, and the instancesof GraphicTool are created only when
the palette is defined. The maindisadvantage here is that GraphicTool subclasses
proliferate, and noneof them does very much.
Abstract Factory doesn't offer much of an improvement, because itrequires an
equally large GraphicsFactory class hierarchy. AbstractFactory would be
preferable to Factory Method only if there werealready a GraphicsFactory class