When creating a class that requires a lot of parameters to be passed when newing Talking about using "builder" for readability and safety
Nutrition Facts is a class that represents nutritional components Amount for one person, amount per container, calories for one person, etc. Let's consider three patterns as an example when you have many fields. ・ Telescoping constructor pattern The disadvantage is that if there are many parameters, it will be difficult to understand what to pass as an argument when newing, and readability will also decrease.
· JavaBeans pattern Readability is improved unlike the telescoping constructor pattern, but inconsistent states occur while setting parameters.
・ Builder pattern The best of telescoping constructors and JavaBeans!
Example 1
//Telescoping constructor pattern
public class NutritionFacts{
private final int servingSize; //(mL)Mandatory
private final int servings; //(Per container)Mandatory
private final int calories; //option
private final int fat; //(g)option
private final int sodium; //(mg)option
private final int carbohydrate; //(g)option
public NutritionFacts(int servingSize, int servings){
this(servingSize, servings, 0, 0, 0, 0);
}
public NutritionFacts(int servingSize, int servings,
int calories ){
this(servingSize, servings, calories, 0, 0, 0);
}
public NutritionFacts(int servingSize, int servings,
int calories, int fat ){
this(servingSize, servings, calories, fat, 0, 0);
}
public NutritionFacts(int servingSize, int servings,
int calories, int fat, int sodium ){
this(servingSize, servings, calories, fat, sodium, 0);
}
public NutritionFacts(int servingSize, int servings,
int calories, int fat, int sodium, carbohydrate ){
this.servingSize = servingSize;
this.servings = servings;
this.calories = calories;
this.fat = fat;
this.sodium = sodium;
this.carbohydrate = carbohydrate;
}
}
//It's hard to see when new
NutritionFacts cocaCola = new NutritionFacts(240, 8, 100, 0, 35, 27);
Example 2
//JavaBeans pattern
public class NutritionFacts{
private int servingSize = -1; //(mL)Mandatory
private int servings = -1; //(Per container)Mandatory
private int calories = 0; //
private int fat = 0; //(g)
private int sodium = 0; //(mg)
private int carbohydrate = 0; //(g)
public NutritionFacts(){ }
//Setter
public void setServingSize(int val) { servingSize = val;}
public void setServings(int val) { servings = val;}
public void setCalories(int val) { calories = val;}
public void setFat(int val) { fat = val;}
public void setSodium(int val) { sodium = val;}
public void setCarbohydrate(int val) { carbohydrate = val;}
}
//It's easy to see when new, but it's a little troublesome if it is accessed while setting
NutritionFact cocaCola = new NutritionFacts();
cocaCola.setServingSize(240);
cocaCola.setServings(8);
cocaCola.setCalories(100);
cocaCola.setSodium(35);
cocaCola.setCarbohydrate(27);
Example 3
//Builder pattern
public class NutritionFacts{
private final int servingSize; //(mL)
private final int servings; //(Per container)
private final int calories; //
private final int fat; //(g)
private final int sodium; //(mg)
private final int carbohydrate; //(g)
public static class Builder{
//Required parameters
private final int servingSize; //(mL)
private final int servings; //(Per container)
//Optional parameters
private int calories = 0; //
private int fat = 0; //(g)
private int sodium = 0; //(mg)
private int carbohydrate = 0; //(g)
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;
}
}
//Easy to see and safe when new!
NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).
calories(100).sodium(35).carbohydrate(27).build();
Recommended Posts