Skip to main content

Builder Design Pattern

Introduction

We will split our discussion into three sections - where to use this design pattern, how to use this design pattern and what is this design pattern. I will discuss what is builder design pattern at the end because the definition of any design pattern will not make sense until you know how and where to use it. In order to discuss where to use builder design pattern, we need to start with the problem statement.

Problem Statement (Where to use builder design pattern):

Create a class to store the following details of a customer in the database:
     private String firstName; //required
     private String lastName; //required
     private String phone; //optional
     private String shippingAddress; //optional
     private String billingAddress; //optional

public class User {
    private String firstName; //required        
    private String lastName; //required        
    private String phone; //optional        
    private String shippingAddress; //optional        
    private String billingAddress; //optional  

    public User(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
    public User(String firstName, String lastName, String phone) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.phone = phone;
    }
    public User(String firstName, String lastName, String phone, String shippingAddress) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.phone = phone;
        this.shippingAddress = shippingAddress;
    }
    public User(String firstName, String lastName, String phone, String shippingAddress,
                String billingAddress) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.phone = phone;
        this.shippingAddress = shippingAddress;
        this.billingAddress = billingAddress;
    }
}

The user class will have 4 different types of constructors based on the number of arguments being passed. The limitation of this design is that if a client reverses the two parameters while passing. The compiler won't complain but the code will break at the runtime. So, a client has to take care of the order of the arguments being passed in the constructor. This problem can be solved by using builder design pattern where a User class will be accessed indirectly by using an instance of UserBuilder class.

How to use Builder design pattern:

public class User {
    private final String firstName; // required        
    private final String lastName; // required        
    private final String phone; // optional        
    private final String shippingAddress; // optional        
    private final String billingAddress; // optional
    private User(UserBuilder builder) {
        this.firstName = builder.firstName;
        this.lastName = builder.lastName;
        this.phone = builder.phone;
        this.shippingAddress = builder.shippingAddress;
        this.billingAddress = builder.billingAddress;
    }

    public String getFirstName() {
        return firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public String getPhone() {
        return phone;
    }
    public String getShippingAddress() {
        return shippingAddress;
    }
    public String getBillingAddress() {
        return billingAddress;
    }

    public class UserBuilder {
        private final String firstName;
        private final String lastName;
        private String phone;
        private String shippingAddress;
        private String billingAddress;

        public UserBuilder(String firstName, String lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
        }
        public UserBuilder phone(String phone) {
            this.phone = phone;
            return this;
        }
        public UserBuilder shippingAddress(String shippingAddress) {
            this.shippingAddress = shippingAddress;
            return this;
        }
        public UserBuilder billingAddress(String billingAddress) {
            this.billingAddress = billingAddress;
            return this;
        }
        private User build() {
            return new User(this);
        }
    }
}

The advantages of this approach are:

  • The User constructor is private, which means that this class cannot be directly instantiated from the client code.
  • The client code is easier to write because doesn't need to worry about the order of the arguments in the constructor.
  • The class is once again immutable. All attributes are final and they’re set on the constructor. Additionally, we only provide getters for them.

What is Builder Design Pattern:

The intent of the Builder design pattern is to separate the construction of a complex object from its representation. By doing so the same construction process can create different representations.

Comments

Popular posts from this blog

Design Pattern in Java

Why Design Pattern In 1994, four authors Erich Gamma, Richard Helm, Ralph Johnson und John Vlissides published a book titled Design Patterns - Elements of Reusable Object-Oriented Software which initiated the concept of Design Pattern in Software development. The idea was to compile a list of common design patterns which can be used by programmers while designing the complex software. All the design patterns in this book are based on the two principles: • Program to an interface, not an implementation. • Favor object composition over inheritance. Let's discuss these two principles in detail. Program to an interface, not an implementation: This principle means that when we create an object, we should create an object for the interface and not the implementation. Example: ArrayList myList = new ArrayList(); //Bad List myList = new ArrayList(); //Good List myList = new TreeList(); // Good In this example, the first declaration i

Types of Design Patterns

Types of Design Patterns Creational Pattern: This design pattern covers the different ways to create an object. We will discuss all of them in the later posts of this blog: Builder Abstract Factory Factory Method Object Pool Prototype Singleton Structural Pattern: Once an object is created, the next job is to create a relationship between the different objects and it can be done using a structural design pattern. The different types of structural design patterns that we will discuss in the future posts are: Adapter Aggregate Bridge Composite Decorator Extensibility Facade FlyWeight Marker Pipes and Filter Opaque Pointer Proxy Behavioral Pattern: In the last two patterns, we have created an object and established a relationship between different objects. Now, we need to figure out ways to communicate with the different objects. Behavioral design pattern helps us in channelizing the communication between the newly created objects. The different type