DEV Community

Karthik Raja
Karthik Raja

Posted on

Implementing Builder Pattern - Abstract Class

Builder Pattern

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. 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;
    }

Enter fullscreen mode Exit fullscreen mode

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();

    }
Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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);
        }
    }

Enter fullscreen mode Exit fullscreen mode

Finally below is the driver code.

Note*: 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();
Enter fullscreen mode Exit fullscreen mode

Output : Dog has 1 tail, 4 legs, 2 ears, 2 eyes

Top comments (1)