Continued from previous post…
The second of way of creating
object is as follows:
Builder
pattern
This is really an interesting
pattern which I have come across lately. Consider a class where there are many
fields in which some are quint essential to be initialized and some may not at
the time of creating object. In that case we would end up giving n number of
constructors in which we may not be knowing which to use and which not to. For
e.g
public class NutritionFacts {
private final int servingSize; // required
private final int servings; // required
private final int calories; // optional
private final int fat; // optional
private final int sodium; // optional
private final int carbohydrate;
public NutritionFacts(int servingSize, int servings) {
super();
this.servingSize = servingSize;
this.servings = servings;
}
public NutritionFacts(int servingSize, int servings, int calories) {
super();
this.servingSize = servingSize;
this.servings = servings;
this.calories = calories;
}
public NutritionFacts(int servingSize, int servings, int calories, int fat) {
super();
this.servingSize = servingSize;
this.servings = servings;
this.calories = calories;
this.fat = fat;
}
public NutritionFacts(int servingSize, int
servings, int calories, int fat, int sodium) {
super();
this.servingSize = servingSize;
this.servings = servings;
this.calories = calories;
this.fat = fat;
this.sodium = sodium;
}
public NutritionFacts(int servingSize, int servings, int calories, int fat, int sodium, int carbohydrate) {
super();
this.servingSize = servingSize;
this.servings = servings;
this.calories = calories;
this.fat = fat;
this.sodium = sodium;
this.carbohydrate = carbohydrate;
}
}
This is called telescoping constructor pattern. Though this pattern may help in some of the
scenarios but it goes out of hand when the parameters go on increasing.
Consider creating an object to the above class, you may not be knowing which
constructor to call for which case.
An alternate we may think of is JavaBeans pattern. By that we can have
only only setters and getters for the parameters and initialize it wherever we
need. But by this way we may not be able to handle the creation. As in, a JavaBean may be in an inconsistent state
partway through its construction.
One more disadvantage associated to this is that the JavaBeans pattern precludes the possibility of making a class
immutable, which in turn would require more effort from the developer to
keep it thread safe.
After coming through all this the
third alternative that we have is builder
pattern. In this instead of making
an object directly, we can call a builder object. Then the client can set optional parameters
if required by calling setters on the builder object. For e.g
public class NutritionFacts {
private final int servingSize;
private final int servings;
private final int calories;
private final int fat;
private final int sodium;
private final int carbohydrate;
public static class Builder {
private int servingSize;
private int servings;
private int calories = 0;
private int fat = 0;
private int sodium = 0;
private int carbohydrate = 0;
public Builder(int
servingSize, int servings) {
this.servingSize = servingSize;
this.servings = servings;
}
public Builder calories(int
val) {
calories = val;
return this;
}
public Builder fat(int
val) {
fat = val;
return this;
}
public Builder sodium(int
val) {
sodium = val;
return this;
}
public Builder carbohydrate(int
val) {
carbohydrate = val;
return this;
}
public NutritionFacts build() {
return new NutritionFacts(this);
}
}
private NutritionFacts(Builder builder) {
servingSize = builder.servingSize;
servings = builder.servings;
calories = builder.calories;
fat =
builder.fat;
sodium
= builder.sodium;
carbohydrate = builder.carbohydrate;
}
}
Now
the object can be created as,
NutritionFacts
cocaCola = new NutritionFacts.Builder(240,
8).calories(100).sodium(45).build();
System.out.println("cocaCola:" + cocaCola.calories);
In order to
have builder instead of going and creating it inside the class we can also have
Builder interface and just implement
it.
Though it has disadvantage of writing builders for each class, but
when you see from the perspective of handling this kind of situation then it is
worth it I think. At least better than
the telescoping and JavaBeans patterns.
{Courtesy: Effective Java - Joshua Bloch}
No comments:
Post a Comment