Using the Builder pattern to create objects in java

Let's say we want to create an immutable class in Java, but there are just way too many fields to keep track of!! We could go the traditional way, and declare a parameterized constructor, along with getters and setters. But this would get real tedious, real soon.

Why? because not only will your constructor parameter list be bulky, object creation can be quite annoying as you have to keep track of individual arguments, which can be unique from object to object. This, by the way, is a code smell - long parameter lists are undesirable.

So what do we do then? Enter the builder pattern.

According to the revered Gang of Four, "the Builder pattern separates the construction of a complex object from its representation so that the same construction process can create different representations."

Let's take a closer look. Imagine, we are creating users for an application. We have to create a separate Builder class, apart from the User class. This can be a separate class or an inner static class.

import java.util.Date;

public final class User {
    private final String nickname;
    private final String password;
    private final String firstname;
    private final String lastname;
    private final String email;
    private final Date created;

    private User(UserBuilder builder) {
        this.nickname = builder.nickname;
        this.password = builder.password;
        this.firstname = builder.firstname;
        this.lastname = builder.lastname;
        this.email = builder.email;
        this.created = builder.created;
    }

    public static UserBuilder getBuilder(String nickname, String password){
        return new User.UserBuilder(nickname, password);
    }

    public static final class UserBuilder {
        private final String nickname;
        private final String password;
        private final Date created;
        private String email;
        private String firstname;
        private String lastname;

        public UserBuilder(String nickname, String password) {
            this.nickname = nickname;
            this.password = password;
            this.created = new Date();
        }

        public UserBuilder firstName(String firstname){
            this.firstname = firstname;
            return this;
        }

        public UserBuilder lastName(String lastname) {
            this.lastname = lastname;
            return this;
        }

        public UserBuilder email(String email) {
            this.email = email;
            return this;
        }

        public User build() {
            return new User(this);
        }


    }

    public String getNickname() {
        return nickname;
    }
    public String getPassword() {
        return password;
    }
    public String getFirstname() {
        return firstname;
    }
    public String getLastname() {
        return lastname;
    }
    public String getEmail() {
        return email;
    }
    public Date getCreated() {
        return new Date(created.getTime());
    }


}

we can create objects in this manner:

User user1 = getBuilder("chuck123", "chocolatesAreGreat").build();

User user2 = getBuilder("chonkMan", "RiDi127837")
                    .email("Ryan@FakeMail.com")
                    .build();

User user3 = getBuilder("imaginaryUsername", "passwordsuperSTRONG")
                      .firstName("Ramesh")
                      .lastName("Vidyanathan")
                      .build();