Design Patterns Tutorial
A tutorial on GOF design patterns. This tutorial is for beginners who are going to learn design patterns for the first time. Each pattern is expalined with suitable examples.

24/11/2013 Categories: Creational Patterns. No Comments on Builder Pattern

Intent:

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

 

Motivation:

A RTF (Rich Text Format) reader application should be able to convert a RTF document to several formats like: plain text or TeX representation or into a text widget which allows users to directly interact. The problem here is, the number of possible conversions is open ended. So, it should be easy to add a new conversion without modifying the reader.

A solution to this problem is, the RTFReader class uses a TextConverter object that converts RTF to other textual repesentations. Whenever the RTReader encounters a RTF token, it notifies the TextConverter object about it. TextConverter object is responsible both for converting the data and for representing the token in a specific format.

The subclasses of TextConverter are specialized for different conversions. For example, the ASCIIConverter converts RTF to plain text. TeXConverter will produce a TeX representation and TextWidgetConverter will produce a complex user interface object that lets the user see and edit the text.

Each converter class takes the responsibility for creating and assembling a complex object and puts it behind an abstract interface. Each converter class is called a builder in the pattern, and the reader is called the director. The Builder pattern separates the algorithm for interpreting a textual format (reader for RTF documents) from how a converted format gets created and represented.

builder pattern motivation example

 

Applicability:

Use the Builder pattern when:

  •  The algorithm for creating a complex object should be independent of the parts that make up the object and how they are assembled.
  •  The construction process must allow different representations for the object that is constructed.

 

Examples where Builder pattern can be applied:

  •  Vehicle manufacturer
  •  Student exams

 

Structure:

builder pattern structure

 

Participants:

The particpants in the Builder pattern are:

Builder: Provides an abstract interface for creating parts of a Product object.

ConcreteBuilder: Constructs and assembles the parts of the Product by implementing the Builder interface. Defines and keeps track of the representation it creates. Provides an interface for retrieving the product.

Director: Constructs an object using the Builder interface.

Product: Represents the complex object under construction. Includes classes that define the constituent parts, including interfaces for assembling the parts into the final result.

 

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 the requests from the Director and adds parts to the product.
  •  The client retrieves the product from the Builder.

 

Consequences:

The benefits and pitfalls of Builder pattern are:

  •  It let’s you vary the product’s internal representation.
  •  It isolates code for construction and representation.
  •  It gives you finer control over the construction process.

 

Implementation:

The client, that may be either another object or the actual client that calls the main() method of the application, initiates the Builder and Director class. The Builder represents the complex object that needs to be built in terms of simpler objects and types. The constructor in the Director class receives a Builder object as a parameter from the Client and is responsible for calling the appropriate methods of the Builder class. In order to provide the Client with an interface for all concrete Builders, the Builder class should be an abstract one. This way you can add new types of complex objects by only defining the structure and reusing the logic for the actual construction process. The Client is the only one that needs to know about the new types, the Director needing to know which methods of the Builder to call.

The Client needs to convert a document from RTF format to ASCII format. There for, it calls the method createASCIIText that takes as a parameter the document that will be converted. This method calls the concrete builder, ASCIIConverter, that extends the Builder, TextConverter, and overrides its two methods for converting characters and paragraphs, and also the Director, RTFReader, that parses the document and calls the builder’s methods depending on the type of token encountered. The product, the ASCIIText, is built step by step, by appending converted characters. The implementation code is as follows:

 

//Abstract Builder
class abstract class TextConverter 
{
	abstract void convertCharacter(char c);
	abstract void convertParagraph();
}

// Product
class ASCIIText 
{
	public void append(char c)
	{ //Implement the code here }
}

//Concrete Builder
class ASCIIConverter extends TextConverter 
{
	ASCIIText asciiTextObj;    //resulting product
	/*converts a character to target representation and appends to the resulting object*/
	void convertCharacter(char c)
	{
		char asciiChar = new Character(c).charValue();
		//gets the ascii character
		asciiTextObj.append(asciiChar);
	}
	void convertParagraph() {}
	ASCIIText getResult()
	{
		return asciiTextObj;
	}
}

//This class abstracts the document object
class Document
{
	static int value;
	char token;
	public char getNextToken()
	{
		//Get the next token
		return token;
	}
}
//Director
class RTFReader 
{
	private static final char EOF='0'; //Delimitor for End of File
	final char CHAR='c';
	final char PARA='p';
	char t;
	TextConverter builder;
	RTFReader(TextConverter obj)
	{
		builder=obj;
	}
	void parseRTF(Document doc)
	{
		while ((t=doc.getNextToken())!= EOF)
		{
			switch (t)
			{
				case CHAR: builder.convertCharacter(t);
				case PARA: builder.convertParagraph();
			}
		}
	}
}

//Client
public class Client
{
	void createASCIIText(Document doc)
	{
		ASCIIConverter asciiBuilder = new ASCIIConverter();
		RTFReader rtfReader = new RTFReader(asciiBuilder);
		rtfReader.parseRTF(doc);
		ASCIIText asciiText = asciiBuilder.getResult();
	}
	public static void main(String args[])
	{
		Client client=new Client();
		Document doc=new Document();
		client.createASCIIText(doc);
		system.out.println("This is an example of Builder Pattern");
	}
}

 

Implementation issues:

Abstract class for products:

In practice the products created by the concrete builders have a structure significantly different, so there is no reason to derive different products from common parent class. This also distinguishes the Builder pattern from the Abstract Factory pattern which creates objects derived from a common type.

Assembly and construction interface:

Builders construct their products in step-by-step fashion. Therefore the Builder class interface must be general enough to allow the construction of products for all kinds of concrete builders. A key design issue concerns the model for the construction and assembly process. A model where the results of construction requests are simply appended to the product is usually sufficient. In the RTF example, the builder converts and appends the next token to the text it has converted so far.

 

Sample Code:

//Product
class Pizza
{
	private String dough = "";
	private String sauce = "";
	private String topping = "";
	public void setDough(String dough)     { this.dough = dough; }
	public void setSauce(String sauce)     { this.sauce = sauce; }
	public void setTopping(String topping) { this.topping = topping; }
}

//Builder
abstract class PizzaBuilder 
{
	protected Pizza pizza;
	public Pizza getPizza() { return pizza; }
	public void createNewPizzaProduct() { pizza = new Pizza(); }
	public abstract void buildDough();
	public abstract void buildSauce();
	public abstract void buildTopping();
}
//ConcreteBuilder
class HawaiianPizzaBuilder extends PizzaBuilder 
{
	public void buildDough()   { pizza.setDough("cross"); }
	public void buildSauce()   { pizza.setSauce("mild"); }
	public void buildTopping() { pizza.setTopping("ham+pineapple"); }
}

//ConcreteBuilder
class SpicyPizzaBuilder extends PizzaBuilder 
{
	public void buildDough()   { pizza.setDough("pan baked"); }
	public void buildSauce()   { pizza.setSauce("hot"); }
	public void buildTopping() { pizza.setTopping("pepperoni+salami"); }
}

//Director
class Waiter
{
	private PizzaBuilder pizzaBuilder;
	public void setPizzaBuilder(PizzaBuilder pb) { pizzaBuilder = pb; }
	public Pizza getPizza() { return pizzaBuilder.getPizza(); }
	public void constructPizza() 
	{
		pizzaBuilder.createNewPizzaProduct();
		pizzaBuilder.buildDough();
		pizzaBuilder.buildSauce();
		pizzaBuilder.buildTopping();
	}
}

//A customer ordering a pizza
class Client
{
	public static void main(String[] args)
	{
		Waiter waiter = new Waiter();
		PizzaBuilder hawaiian_pizzabuilder = new HawaiianPizzaBuilder();
		PizzaBuilder spicy_pizzabuilder = new SpicyPizzaBuilder();
		waiter.setPizzaBuilder( hawaiian_pizzabuilder );
		waiter.constructPizza();
		Pizza pizza = waiter.getPizza();
	}
}

 

builder pattern real world example

 

Known Uses:

Builder pattern is used commonly across Smalltalk-80:

  •  The Parser class in the compiler subsystem is a Director that takes a ProgramNodeBuilder object as an argument.
  •  ClassBuilder is a builder that classes use to create subclassses for themselves. In this case a Class is both Director and a Builder.
  •  ByteCodeStream is a builder that creates a compiled method as a byte array.

 

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 (either simple or complex). 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 a builder often builds.

 

Example Builder classes in java API:

  • java.lang.StringBuilder (unsynchronized)
  • java.lang.StringBuffer (synchronized)
  • java.nio.ByteBuffer (also CharBuffer, ShortBuffer, IntBuffer, LongBuffer, FloatBuffer and DoubleBuffer)
  • javax.swing.GroupLayout.Group

All implementations of java.lang.Appendable

 

Non-software example:

The Builder pattern separates the construction of a complex object from its representation, so that the same construction process can create different representation. This pattern is used by fast food restaurants to construct children’s meals. Children’s meals typically consist of a main item, a side item, a drink, and a toy (e.g., a hamburger, fries, coke, and toy car). Note that there can be variation in the contents of the children’s meal, but the construction process is the same. Whether a customer orders a hamburger, cheeseburger, or chicken, the process is the same. The employee at the counter directs the crew to assemble a main item, side item, and toy. These items are then placed in a bag. The drink is placed in a cup and remains outside of the bag. This same process is used at competing restaurants.

builder pattern non software example

Suryateja Pericherla

Suryateja Pericherla

Hello, I am Suryateja Pericherla working as an Asst. Professor in CSE department at Vishnu Institute of Technology. I write articles to share my knowledge and make people knowledgeable regarding certain topics.
Suryateja Pericherla

Latest posts by Suryateja Pericherla (see all)

Related Links:

Note: Do you have a question on this article or have a suggestion to make this article better? You can ask or suggest us by filling in the below form. After commenting, your comment will be held for moderation and will be published in 24-48 hrs.
Scroll Up