Sunday, 16 December 2007

Builder Pattern In Java

Today let us discuss another GOF creational pattern "Builder Pattern".

Intent:
-> The intention is to seperate the construction of a complex object from its representation so that the same construction process can create different representations.
-> Parse a complex representation,create one of several targets.

Problem:
An application needs to create elements of a complex aggregate.The specification for the aggregate exists on secondary storage and one of many representations needs to be built in primary storage.

Structure Summary:
1) Define the steps for creating a complex object,and put the interface of these steps in an abstract base class.
2) Bury each possible implementation of these steps in its own derived class.
3) Define a wrapper that holds an instance of the "target" derived type.
4) Wrapper parses the common input format and delegates it to the target implementation.

Unlike creational patterns that construct products in one shot,the builder pattern construts the product step by step.

Rules of thumb

Sometimes creational patterns are complementory.Builder can use one of the other patterns to implement which components get built.Abstract Factory,Builder,and Prototype can use Singleton in their implementations.[GoF,p81,134]

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]

Builder often builds a composite[GoF,p106]

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]

Please always remember that builder is one of the implementations of AbstractFactory.Surely it can use other factories to build the parts of the product.

Often builder pattern builds composite pattern a structure pattern.

Concrete Builder:
Provide implementation for builder.Construct and assemble parts to built the objects.Make concrete and lay it.

Definition: Construct a complex object from simple objects step by step.

Where to use & Benefits

-> Make a complex object by specifying its type and content.The build object is protected from the details of its construction.

-> Want to decouple the process of building a complex object from the parts that make up the object.

-> Isolate Code from Construction and representation.

-> Give us finer control over the construction process.

-> Often Composite,Abstract Factory pattern,Prototype and Singleton are used to build a complex object.

Diff between builder and factory pattern?
Builder builds one complex object through several method calls.With Abstract Factory,every method call returns its own little object.

Examples:->
Probably writing a pizza program.Every gradient can be designed as a class.One pizza at least consists of several gradients.Different pizza has diff gradients.A builder pattern may be adopted.
->

Construction of a house? To build a house we may take several steps
:- Build foundation.
:- Build Frame
:- Build Interior
:- Build Exterior

Consequences Of Builder Pattern:
-> A Builder lets us vary internal representation of the product it builds.It also hides the details of how the product is assembled.
-> Each specific builder is independent of the others and of the rest of the program.This improves modularity and makes the addition of other builders relatively simple.
-> Because each builder constructs the final product step-by-step,depending on the data,we have more control over each final product that a builder constructs.


Below example gives one implementation of builder pattern.


import java.util.ArrayList;
import java.util.List;

class DesignPatterns {

private List<String> creationalDesignPatterns;
private List<String> structuralDesignPatterns;
private List<String> behavorialDesignPatterns;

public List<String> getBehavorialDesignPatterns() {
return behavorialDesignPatterns;
}
public void setBehavorialDesignPatterns(List<String> behavorialDesignPatterns) {
this.behavorialDesignPatterns = behavorialDesignPatterns;
}
public List<String> getCreationalDesignPatterns() {
return creationalDesignPatterns;
}
public void setCreationalDesignPatterns(List<String> creationalDesignPatterns) {
this.creationalDesignPatterns = creationalDesignPatterns;
}
public List<String> getStructuralDesignPatterns() {
return structuralDesignPatterns;
}
public void setStructuralDesignPatterns(List<String> structuralDesignPatterns) {
this.structuralDesignPatterns = structuralDesignPatterns;
  }
}

abstract class DesignPatternsBuilder {

protected DesignPatterns designPatterns;

public DesignPatterns getDesignPatterns() {
return designPatterns;
}

public void createDesignPatterns() {
designPatterns=new DesignPatterns();
}

public abstract void buildCreationalDesignPatterns();
public abstract void buildStructuralDesignPatterns();
public abstract void buildBehavorialDesignPatterns();
}

class CreationalDesignPatternsBuilder extends DesignPatternsBuilder {

public void buildCreationalDesignPatterns() {
List<String> creationalDesignPatterns=new ArrayList<String>();
creationalDesignPatterns.add("Abstract Factory");
creationalDesignPatterns.add("Builder");
creationalDesignPatterns.add("Factory Method");
creationalDesignPatterns.add("Prototype");
creationalDesignPatterns.add("Singleton");
designPatterns.setCreationalDesignPatterns(creationalDesignPatterns);
}

public void buildStructuralDesignPatterns() {}
public void buildBehavorialDesignPatterns() {}
}

//.. similarly for StructuralDesignPatterns and BehavorialDesignPatterns classes as well.

class DesignPatternReader {
private DesignPatternsBuilder db;

public void setDesignPatternsBuilder(DesignPatternsBuilder db) {
this.db = db;
}

public DesignPatterns getDesignPattern() {
return db.getDesignPatterns();
}

public void constructDesignPatterns() {
db.createDesignPatterns();
db.buildCreationalDesignPatterns();
// Similarly for other patterns as well.....
  }
}

public class BuilderPatternExample {
public static void main(String[] args) {
DesignPatternReader dpr=new DesignPatternReader();
CreationalDesignPatternsBuilder cdpb=new CreationalDesignPatternsBuilder();
dpr.setDesignPatternsBuilder(cdpb);
dpr.constructDesignPatterns();
List<String> cps=dpr.getDesignPattern().getCreationalDesignPatterns();
int i=1;
for (String str : cps) {
System.out.println("Creattional Patterns:" + i + ":" + str);
i++;
    }

  }
}



Hope this explanation helps if any.

2 comments:

Anonymous said...

Excellent attempt. Looking forward to more such posts.

JP said...

thanks gopi.