Abstract Factory
Intent
Provide an interface for creating families of related or dependent
objects without specifying their concrete classes.
Problem
If an application is to be portable, it needs to encapsulate platform
dependencies. These "platforms" might include: windowing system,
operating system, database, etc. Too often, this encapsulatation is
not engineered in advance, and lots of #ifdef case statements with
options for all currently supported platforms begin to procreate like
rabbits throughout the code.
Discussion
Provide a level of indirection that abstracts the creation of families
of related or dependent objects without directly specifying their
concrete classes. The "factory" object has the responsibility for
providing creation services for the entire platform family. Clients
never create platform objects directly, they ask the factory to do that
for them.
This mechanism makes exchanging product families easy because the
specific class of the factory object appears only once in the
application - where it is instantiated. The application can wholesale
replace the entire family of products simply by instantiating a
different concrete instance of the abstract factory.
Because the service provided by the factory object is so pervasive, it
is routinely implemented as a Singleton.
Structure
This diagram is from javacoder.net.
Example
The purpose of the Abstract Factory is to provide an interface
for creating families of related objects, without specifying concrete
classes. This pattern is found in the sheet metal stamping equipment
used in the manufacture of Japanese automobiles. The stamping equipment
is an Abstract Factory which creates auto body parts. The same
machinery is used to stamp right hand doors, left hand doors, right
front fenders, left front fenders, hoods, etc. for different models of
cars. Through the use of rollers to change the stamping dies, the
concrete classes produced by the machinery can be changed within three
minutes. [Michael Duell, "Non-software examples of software design
patterns", Object Magazine, Jul 97, p54]
Rules of thumb
Sometimes creational patterns are competitors: there are cases when
either Prototype or Abstract Factory could be used profitably. At
other times they are complementory: Abstract Factory might store a set
of Prototypes from which to clone and return product objects [GOF,
p126], Builder can use one of the other patterns to implement which
components get built. Abstract Factory, Builder, and Prototype can use
Singleton in their implementation. [GOF, pp81,134]
Abstract Factory, Builder, and Prototype define a factory object that's
responsible for knowing and creating the class of product objects, and
make it a parameter of the system. Abstract Factory has the factory
object producing objects of several classes. Builder has the factory
object building a complex product incrementally using a correspondingly
complex protocol. Prototype has the factory object (aka prototype)
building a product by copying a prototype object. [GOF, p135]
Abstract Factory classes are often implemented with Factory Methods,
but they can also be implemented using Prototype. [GOF, p95]
Abstract Factory can be used as an alternative to Facade to hide
platform-specific classes. [GOF, p193]
Builder focuses on constructing a complex object step by step.
Abstract Factory emphasizes a family of product objects (either simple
or complex). Builder returns the product as a final step, but as far
as the Abstract Factory is concerned, the product gets returned
immediately. [GOF, p105]
Often, designs start out using Factory Method (less complicated, more
customizable, subclasses proliferate) and evolve toward Abstract
Factory, Prototype, or Builder (more flexible, more complex) as the
designer discovers where more flexibility is needed. [GOF, p136]