CHAPTER 15

image

Builder Patterns

GoF Definition: Separate the construction of a complex object from its representation so that the same construction processes can create different representations.

Concept

The pattern is useful when a creational algorithm of a complex object is independent of the assembly of the parts of the object. The construction process is also capable of building a different representation of that object under consideration.

Real-Life Example

To create a computer, different parts are assembled depending upon the order received by the customer (e.g., a customer can demand a 500 GB hard disk with an Intel processor; another customer can choose a 250 GB hard disk with an AMD processor).

Computer World Example

We sometimes need to convert one text format to another text format (e.g., RTF to ASCII text).

Illustration

Here the participants are IBuilder, Car, MotorCycle, Product, and Director. The first three are very straightforward—Car and MotorCycle are implementing the IBuilder interface. IBuilder is used to create parts of the Product object where Product represents the complex object under construction. The assembly process is described in Product. We can see that we have used the Linked List data structure in Product for this assembly operation.

Car and MotorCycle are the concrete implementations. They have implemented IBuilder interface. That’s why they needed to BuildBody(), InsertWheels(), AddHeadlights(), and finally GetVehicle(). We use the first three methods to build the body of the vehicle, insert the number of wheels into it, and add headlights to the vehicle. GetVehicle() will return the ultimate product. Finally, Director will be responsible for constructing the ultimate vehicle. Director will build the product with IBuilder interface. He is calling the same Construct() method to create different types of vehicles.

Please go through the code to see how different parts are assembled for this pattern.

UML Class Diagram

9781484218013_unFig15-01.jpg

Package Explorer view

High-level structure of the parts of the program is as follows:

9781484218013_unFig15-02.jpg

Implementation

package builder.pattern.demo;
import java.util.LinkedList;

// Builders common interface
interface IBuilder
{
        void BuildBody();
        void InsertWheels();
        void AddHeadlights();
        Product GetVehicle();

}

// Car is ConcreteBuilder
class Car implements IBuilder
{
        private Product product = new Product();

        @Override
        public void BuildBody()
        {
                product.Add("This is a body of a Car");
        }
        @Override
        public void InsertWheels()
        {
                product.Add("4 wheels are added");
        }
        @Override
        public void AddHeadlights()
        {
                product.Add("2 Headlights are added");
        }
        @Override
        public  Product GetVehicle()
        {
                return product;
        }

}

// Motorcycle is a ConcreteBuilder
class MotorCycle implements IBuilder
{
        private Product product = new Product();

        @Override
        public  void BuildBody()
        {
                product.Add("This is a body of a Motorcycle");
        }
        @Override
        public void InsertWheels()
        {
                product.Add("2 wheels are added");
        }
        @Override
        public void AddHeadlights()
        {
                product.Add("1 Headlights are added");
        }
        @Override
        public  Product GetVehicle()
        {
                return product;
        }
}

// "Product"
class Product
{
        // We can use any data structure that you prefer. We have used LinkedList here.
        private LinkedList<String> parts;
        public Product()
        {
                parts = new LinkedList<String>();
        }

        public void Add(String part)
        {
                //Adding parts
                parts.addLast(part);
        }

        public void Show()
        {
                System.out.println(" Product completed as below :");
                for(int i=0;i<parts.size();i++)
                {
                        System.out.println(parts.get(i));
                }
        }
 }
// "Director"
class Director
{
        IBuilder myBuilder;

        // A series of steps—for the production
        public void Construct(IBuilder builder)
        {
                myBuilder=builder;
                myBuilder.BuildBody();
                myBuilder.InsertWheels();
                myBuilder.AddHeadlights();
        }
}
class BuilderPatternEx
{
        public static void main(String[] args)
        {
                System.out.println("***Builder Pattern Demo*** ");

                Director director = new Director();

                IBuilder carBuilder = new Car();
                IBuilder motorBuilder = new MotorCycle();

                // Making Car
                director.Construct(carBuilder);
                Product p1 = carBuilder.GetVehicle();
                p1.Show();

                //Making MotorCycle
                director.Construct(motorBuilder);
                Product p2 = motorBuilder.GetVehicle();
                p2.Show();
        }
}

Output

9781484218013_unFig15-03.jpg

Note

  1. Here we separate the code of assembling from its representation. So, it hides the complex construction process and represents it as a simple process.
  2. Here we focus on “how the product will be made.”
  3. In general, we have only one method which will finally return the complete object. Other methods will be responsible for partial creation process only.
  4. It requires some amount of code duplication—which is considered a drawback with this pattern.
  5. Also, if we want a mutable object (an object which can be modified after the creational process is over), we should not use this pattern.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.138.178