Separate the construction of a complex object from its representation so that the same construction process can create different representations.
-
The algorithm for creating a complex object should be independent of the parts that make up the object and how they're assembled.
-
The construction process must allow different representations for the object that's constructed.
-
The client creates the
Director
object and configures it with the desiredBuilder
object. -
Director
notifies theBuilder
whenever a part of the product should be built. -
Builder
handles requests from theDirector
and adds parts to the product. -
The client retrieves the product from the builder.
-
It lets you vary a product's internal representation. The
Builder
hides the implementation and internal structure of the product and how it gets assembled. You can vary theProduct
's internal representation by defining a new kind ofBuilder
. -
It isolates code for construction and representation. Client's don't know anything about classes that define the product's internal structure, such classes don't appear in
Builder
's interface. EachConcreteBuilder
contains all the code to create and assemble a particular kind of product. The code is wrirten once, then differentDirector
can reuse it to buildProduct
variants from the same set of parts. -
It gives you finer control over the construction process. Unlike creational patterns that construct products in one shot, the Builder pattern constructs the product step by step under the
Director
's control. Only when the product is finished does theDirector
retrieve it from the builder. This gives you finer control over the construction process and consequently the internal structure of the resulting product.
Abstract Factory is similar to Builder in that it too may construct complex objects. The primary difference is that the Builder pattern focuses on constructing a complex object step by step. Abstract Factory's emphasis is on families of product objects. Builder returns the product as a final step, but as far as the Abstract Factory pattern is concerned, the product gets returned immediately.
A Composite is what the builder often builds.
Typically there's an abstract Builder
class that defines an operation for each component that a Director
may ask it to create. A ConcreteBuilder
class overrides operations for components it's interested in creating.
Here are other implementation issues to consider:
-
Assembly and construction interface.
Builder
class interface must be general enough to allow construction of products for all kinds ofConcreteBuilder
s. A model where the results of construction requests are simply appended to the product is usually sufficient. But sometimes you might need to access to parts of the product constructed earlier. -
Why no abstract class for products?. In the common case, the products produced by the concrete builders differ so greatly in their representations that there is little to gain from giving different products a common parent class. Because the client usually configures the
Director
with the properConcretBuilder
, the client is in a position to know which concrete subclass ofBuilder
is in use and can handle its products accordingly. -
Empty methods as default in Builder. Let clients override only the operations they're interested in.
A reader for the RTF (Rich Text Format) document exchange exchange format should be able to convert RTF to many text formats. The problem is that the number of possible conversions is open-ended. So it should be easy to add a new conversion without modifying the reader.
A solution is to configure the RTFReader
class with a TextConverter
object that converts RTF to another textual representation. As the RTFReader
parses the RTF document, it uses the TextConverter
to perform the conversion. Whenever the RTFReader
recognizes an RTF token (either plain text or an RTF control word), it issues a request to the TextConverter
to convert the token. TextConverter
objects are responsible both for performing the data conversion and for representing the token in a particular format.
Subclasses of TextConverter
specialize in different conversions and formats. For example, an ASCIIConverter
ignores requests to convert anything except plain text. A TeXConvertere
, on the other hand, will implement operations for all requests in order to produce a TeX representation. A TextWidgetConverter
will produce a complex user interface object that lets the user see and edit the text.
Each kind of converter class takes the mechanism for creating and assembling a complex object and puts it behind an abstract interface. The converter is separate from the reader, which is responsible for parsing an RTF document.
The Builder pattern captures all these relationships. Each converter class is called a builder in the pattern, and the reader is called the directior.
Applied to this example, the Builder pattern separates the algorithm for interpreting a textual format (that is, the parser for RTF documents) from how a converted format gets created and represented. This lets us reuse the RTFReader
's parsing algorithm to create different text representations, just by configuring the RTFReader
with different subclasses of TextConverter
.