Skip to content

Latest commit

 

History

History

builder

Builder

Intent

Separate the construction of a complex object from its representation so that the same construction process can create different representations.

Applicability

  • 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.

Collaborations

Builder structure

Builder collaborations

  • The client creates the Director object and configures it with the desired Builder object.

  • Director notifies the Builder whenever a part of the product should be built.

  • Builder handles requests from the Director and adds parts to the product.

  • The client retrieves the product from the builder.

Consequences

  1. 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 the Product's internal representation by defining a new kind of Builder.

  2. 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. Each ConcreteBuilder contains all the code to create and assemble a particular kind of product. The code is wrirten once, then different Director can reuse it to build Product variants from the same set of parts.

  3. 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 the Director retrieve it from the builder. This gives you finer control over the construction process and consequently the internal structure of the resulting product.

Related Patterns

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.

Implementation

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:

  1. Assembly and construction interface. Builder class interface must be general enough to allow construction of products for all kinds of ConcreteBuilders. 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.

  2. 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 proper ConcretBuilder, the client is in a position to know which concrete subclass of Builder is in use and can handle its products accordingly.

  3. Empty methods as default in Builder. Let clients override only the operations they're interested in.

Motivation

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.

Builder example

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.