Java | Builder Pattern for Optional Parameters
“Consider a builder when faced with many constructor parameters” ~ Joshua Block’s, Effective Java
Classes that have many optional parameters can use builder pattern to create instances of these classes according to Joshua Block’s Effective Java Item-2.
How to Create Instances of Classes with Many Optional Parameters?
- For example, we have
Mobile.java
class that has one required parameter and many optional ones.
public class Mobile {
String brand; //required
String model;
String color;
double display;
double price;
}
- To create an instance of this class we can have a constructor that accepts all parameters. While this seems to be a simple solution, it will require the passing of values for parameters that might not needed.
public Mobile(String brand, String model, String color, double display, double price) {
this.brand = brand;
this.model = model;
this.color = color;
this.display = display;
this.price = price;
}
- Another way is to write a constructor or “static factory method” for each possible case. However, this way might not be practical and will be faced with the language restriction of not allowing more than one constructor with the same signature.
public Mobile(String brand, String model) {
this.brand = brand;
this.model = model;
}
// not allowed! we already have a constructor with similar signature
public Mobile(String brand, String color) {
this.brand = brand;
this.color = color;
}
- A third possible solution is JavaBean in which we call default constructor “that has no parameters” and then set parameters using setter methods. However, since the creation of an instance needs multiple calls we need to ensure thread safety and consistency of passed values.
Mobile mobile = new Mobile();
mobile.setBrand("Apple");
mobile.setSize(5.4);
...
- An alternative solution that overcomes all the disadvantages of previous ones is Builder Pattern
Builder Pattern
- Builder pattern is an efficient way to create instances of classes that have many optional parameters.
- Builder pattern has many advantages over other alternative ways e.g. JavaBeans.
- Builder pattern works by creating a builder object with required parameters then setter-like methods are called to set optional parameters. The actual instance is created by calling build() method.
Mobile mobile = new Mobile.Builder("Apple").display(5.4).model("iPhone 13").build();
public class Mobile {
private String brand; //required
private String model;
private String color;
private double display;
private double price;
// getters
private Mobile(Builder builder) {
// optional paramters only
this.model = builder.model;
this.color = builder.color;
this.display = builder.display;
this.price = builder.price;
}
public static class Builder{
//required
private String brand;
// optional
private String model;
private String color;
private double display;
private double price;
public Builder(String brand) {
this.brand = brand;
}
// optional parameters setters
public Builder model(String model) {
this.model = model;
return this;
}
public Builder color(String color) {
this.color = color;
return this;
}
public Builder display(double display) {
this.display = display;
return this;
}
public Builder price(double price) {
this.price = price;
return this;
}
// build
public Mobile build() {
return new Mobile(this);
}
}
}