Friday, April 3, 2015

Builder Design Pattern

Design Pattern > Creational Design Pattern > Builder Design Pattern

As per GOF builder pattern “Separate the construction of a complex object from its representation so that the same construction process can create different representations.”
In this pattern client application will provide parameter (used to create complex object) to builder and builder will provide the final complex object to client.
Builder pattern solves the problem of increasing parameter in object constructor. For example suppose you have created a AnimalBuilder class which create different animal objects by assembling different parts of animal as parameters passed in constructor. Parameters can be animalType, head, tail, body, leg, animalVoice, colour etc.
Public class AnimalBuilder {
                public AnimalBuilder(String animalType, AnimalHead head, String tail, String body, String leg, Voice animalVoice, String colour){
                // initializing object
    }
}
This approach is error prone, you need to be very careful about passing the parameters while creating animal object. Since most of the parameters are of same type i.e. String, So tail can be passed instead of leg or body and created animal object would look like demon ;-) .
This can be resolved using builder pattern in which there is a builder class for each animal type (builder class assembles all the animal parts), this builder pass to a director class, which ultimately creates the final animal object.
the key terms in this pattern are –
  • Builder class that specifies an abstract interface for creating parts of a Product object.
  • ConcreteBuilder that constructs and puts together parts of the product by implementing the Builder interface. It defines and keeps track of the representation it creates and provides an interface for saving the product.
  • Director class that constructs the complex object using the Builder interface.
  • Product class that represents the complex object that is being built.
Java Implementation:
Assume that in toy factory assembly software assembles different animal parts and make a toy as final product. Implementation in builder pattern would include following classes:

/**
 * Product abstract class that holds the basic information for a product. It helps us build multiple products.
 */
package com.kmingle.builder;

public abstract class Animal{

       private String head;
       private String body;
       private String arm;
       private String leg;
       private String tail;
      
       public String getHead() {
              return head;
       }
       public void setHead(String head) {
              this.head = head;
       }
       public String getBody() {
              return body;
       }
       public void setBody(String body) {
              this.body = body;
       }
       public String getArm() {
              return arm;
       }
       public void setArm(String arm) {
              this.arm = arm;
       }
       public String getLeg() {
              return leg;
       }
       public void setLeg(String leg) {
              this.leg = leg;
       }
       public String getTail() {
              return tail;
       }
       public void setTail(String tail) {
              this.tail = tail;
       }
      
       public abstract void makeNoise();
      
       public void printAnimalDetails(){
              System.out.println(getHead());
              System.out.println(getBody());
              System.out.println(getArm());
              System.out.println(getLeg());
              System.out.println(getTail());
              makeNoise();
       }
}

/**
 * Product Class
 */
package com.kmingle.builder;

public class Lion extends Animal {
      
       @Override
       public void makeNoise() {
              System.out.println("Lion Roaring.......");
       }

}

/**
 * Product Class
 */
package com.kmingle.builder;

public class Swan extends Animal {

       @Override
       public void makeNoise() {

              System.out.println("Swan sound");
       }
      
}


/**
 * Abstract Builder class contains all the building methods to construct a general product (Animal)
 */
package com.kmingle.builder;

public abstract class AnimalBuilder {

       Animal animal;
       protected abstract void assembleAnimalHead();
       protected abstract void assembleAnimalBody();
       protected abstract void assembleAnimalArm();
       protected abstract void assembleAnimalLeg();
       protected abstract void assembleAnimalTail();
}

/**
 *  Concrete Builder Class
 */
package com.kmingle.builder;

public class LionBuilder extends AnimalBuilder {

       public LionBuilder(){
              animal = new Lion();
       }
      
       @Override
       protected void assembleAnimalHead() {
              animal.setHead("Lion's head assembled");
       }

       @Override
       protected void assembleAnimalBody() {
              animal.setBody("Lion's body assembled");
       }

       @Override
       protected void assembleAnimalArm() {
              animal.setArm("Lion's arm assembled");
       }

       @Override
       protected void assembleAnimalLeg() {
              animal.setLeg("Lion's leg assembled");
       }

       @Override
       protected void assembleAnimalTail() {
              animal.setTail("Lion's tail assembled");
       }

}


/**
 *  Concrete Builder Class
 */
package com.kmingle.builder;

public class SwanBuilder extends AnimalBuilder {

       public SwanBuilder(){
              animal = new Swan();
       }
      
       @Override
       protected void assembleAnimalHead() {
              animal.setHead("Swan's head assembled");
       }

       @Override
       protected void assembleAnimalBody() {
              animal.setBody("Swan's body assembled");
       }

       @Override
       protected void assembleAnimalArm() {
              animal.setArm("Swan's arm assembled");
       }

       @Override
       protected void assembleAnimalLeg() {
              animal.setLeg("Swan's leg assembled");
       }

       @Override
       protected void assembleAnimalTail() {
              animal.setTail("Swan's tail assembled");
       }

}


/**
 * Director Class actually drives the procedure with the necessary build parts and sequence of building an animal.
 */
package com.kmingle.builder;

public class AssemblyMachine {

       public void assembleAnimal(AnimalBuilder animalBuilder){
              animalBuilder.assembleAnimalHead();
              animalBuilder.assembleAnimalBody();
              animalBuilder.assembleAnimalArm();
              animalBuilder.assembleAnimalLeg();
              animalBuilder.assembleAnimalTail();
       }
}


/**
 * Client Class that creates dicrector and different animalbuilder objects to build final toy product
 */
package com.kmingle.builder;

public class Worker {

       public static void main(String[] args) {
              AssemblyMachine assemblyMachine = new AssemblyMachine();
             
              System.out.println("building Lion toy");
              LionBuilder lionBuilder = new LionBuilder();
              assemblyMachine.assembleAnimal(lionBuilder);
              lionBuilder.animal.printAnimalDetails();
             
              System.out.println("building Swan toy");
              SwanBuilder swanBuilder = new SwanBuilder();
              assemblyMachine.assembleAnimal(swanBuilder);
              swanBuilder.animal.printAnimalDetails();
       }

}

Out Put:
building Lion toy
Lion's head assembled
Lion's body assembled
Lion's arm assembled
Lion's leg assembled
Lion's tail assembled
Lion Roaring.......
building Swan toy
Swan's head assembled
Swan's body assembled
Swan's arm assembled
Swan's leg assembled
Swan's tail assembled
Swan sound


Now we have seen that as per Builder pattern definition AnimalBuilder Separates the construction of a complex object(Lion/Swan ) from its representation so that the same construction process(in AssemblyMachine) can create different representations(Lion/Swan etc).

No comments:

Total Pageviews