builder pattern real world example in java

The builder pattern is an object creation software design pattern. The intention of the builder pattern is to find a solution to the telescoping constructor anti-pattern that occurs when the increase of object constructor parameter combination leads to an exponential list of constructors. Instead of using numerous constructors, the builder pattern uses another object, a builder, that receives each initialization parameter step by step and then returns the resulting constructed object at once.

Instead of making the desired object directly, the client calls a constructor (or static factory) with all of the required parameters and gets a builder object. Then the client calls setter-like methods on the builder object to set each optional parameter of interest. Finally, the client calls a parameterless build method to generate the object, which is immutable.

Lets take an example consider the case of a class representing a alert which occurs when there is some issue in the network and based on the source of the alert the parameters that will be received varies drastically . Lets say if the alert is from a array we get somewhere around 9 properties and an alert from the switch will have only 4 parameters.What sort of constructors or static factories should you write for such a class. In these scenarios we use the telescoping constructor pattern, in which we provide a constructor with only the required parameters, another with a single optional parameter, a third with two optional parameters and so on.

Though telescoping constructor pattern works, but it is hard to write client code when there are many parameters, and harder still to read it.But luckily, there is Builder pattern for the rescue.

Lets define a builder interface


public interface Builder<T> {

public T build();

}

Builder pattern for creating alert object


public class Alert {

private int subElementId;
private int metricMetadataId;
private int metricMetadataHourlyId;
private float metricValue;
private String createdTimestamp;
private float meanDeviation;
private int thresold;
private String durationType;
private int durationInterval;

public static class AlertBuilder implements Builder<Alert> {

private int subElementId;
private int metricMetadataId;
private int metricMetadataHourlyId;
private float metricValue;
private String createdTimestamp;
private float meanDeviation;
private int thresold;
private String durationType;
private int durationInterval;

public AlertBuilder(int subElementId, int metricMetadataId, int metricMetadataHourlyId) {

this.subElementId = subElementId;
this.metricMetadataId = metricMetadataId;
this.metricMetadataHourlyId = metricMetadataHourlyId;

}

public AlertBuilder metricValue(float metricValue) {
this.metricValue = metricValue;
return this;
}

public AlertBuilder createdTimestamp(String createdTimestamp) {
this.createdTimestamp = createdTimestamp;
return this;
}

public AlertBuilder meanDeviation(float meanDeviation) {
this.meanDeviation = meanDeviation;
return this;
}

public AlertBuilder thresold(int thresold) {
this.thresold = thresold;
return this;
}

public AlertBuilder durationType(String durationType) {
this.durationType = durationType;
return this;
}

public AlertBuilder durationInterval(int durationInterval) {
this.durationInterval = durationInterval;
return this;
}

@Override
public Alert build() {

return new Alert(this);
}

}

public Alert(AlertBuilder builder) {
this.subElementId = builder.subElementId;
this.metricMetadataId = builder.metricMetadataId;
this.metricMetadataHourlyId = builder.metricMetadataHourlyId;
this.metricValue = builder.metricValue;
this.createdTimestamp = builder.createdTimestamp;
this.meanDeviation = builder.meanDeviation;
this.thresold = builder.thresold;
this.durationType = builder.durationType;
this.durationInterval = builder.durationInterval;
}

@Override
public String toString() {
return "Alert [subElementId=" + subElementId + ", metricMetadataId=" + metricMetadataId
+ ", metricMetadataHourlyId=" + metricMetadataHourlyId + ", metricValue=" + metricValue
+ ", createdTimestamp=" + createdTimestamp + ", meanDeviation=" + meanDeviation + ", thresold="
+ thresold + ", durationType=" + durationType + ", durationInterval=" + durationInterval + "]";
}

}

Driver code to test


public class Driver {

public static void main(String[] args) {

Alert alert = new Alert.AlertBuilder(1212, 3434, 21212).metricValue(34).createdTimestamp("2017-12-23")
.meanDeviation(70).thresold(60).durationType("SW").durationInterval(5).build();
System.out.println(alert);

Alert alert2 = new Alert.AlertBuilder(1212, 3434, 21212).metricValue(34).createdTimestamp("2017-12-23").build();
System.out.println(alert2);

}