Implementing Builder Pattern - Abstract Class
Tags: java, oop, design
Published: 2022-05-16 17:23:32

#<u>Builder Pattern</u>

Let's take a look why need builder pattern...

When we have a Class with N number of fields to be initialized in the constructor, we end up with [Telescoping Constructor](https://www.vojtechruzicka.com/avoid-telescoping-constructor-pattern/). The problem with the telescoping constructor is its difficult to remember the order of arguments to be passed while calling the constructor.

The Builder Pattern is an object creation design pattern which intent is to separate the construction of a complex object from its representation. By doing so, the same construction process can lead to different representations. 

The way to design this pattern is to create a internal static class named `<ClassName>Builder`, the methods of this class should allow to set the fields. Finally we have a build() method which in turn calls the constructor of the outer class which takes the builder class object as an argument to create a new object.

In the upcoming example we will look how to implement Builder Pattern with Abstract class

```
public abstract class Animals {

    private int legs;
    private int eyes;
    private int ears;

    //getters //toString

    //Constructor has parameter of type builder 
   
    public Animals(AnimalBuilder builder) {
        this.legs = builder.legs;
        this.eyes = builder.eyes;
        this.ears = builder.ears;
    }
   
```
Below is the Builder class of Animal Abstract class, here in this example it is a inner class and the build() method should be abstract which must be implemented by subclasses.

```
public abstract static class AnimalBuilder {

        private int legs;
        private int eyes;
        private int ears;

        public AnimalBuilder setLegs(int legs) {
            this.legs = legs;
            return this;
        }

        public AnimalBuilder setEyes(int eyes) {
            this.eyes = eyes;
            return this;
        }

        public AnimalBuilder setEars(int ears) {
            this.ears = ears;
            return this;
        }

        public abstract Animals build();

    }
```

Now let's extend the above **abstract class** `Animals` on to **concrete class** `Dog`

```
public class Dog extends Animals{

    private int tail;

    public Dog(DogBuilder builder) {
        super(builder);
        this.tail = builder.tail;
    }
    
//getters and toString

```

We should extend the internal abstract class `AnimalBuilder` of abstract class `Animal`

```
public static class DogBuilder extends Animals.AnimalBuilder {


        private int tail;

        public DogBuilder setTail(int tail) {
            this.tail = tail;
            return this;
        }

        @Override
        public Animals build() {
            return new Dog(this);
        }
    }

```

Finally below is the driver code.

<u>Note*:</u> in the below example we need to down cast the object to Dog explicitly as the super class method return type is Animal. 
This can be avoided if we use generics.
```
Dog dog = (Dog) new Dog.DogBuilder().setTail(1).setLegs(4).setEars(2).setEyes(2).build();
```
`Output : Dog has 1 tail, 4 legs, 2 ears, 2 eyes`