Valid Java, inclutivejava
The static factory and the constructor have a common limitation: they cannot be well expanded when a large number of parameters are encountered.
Let's talk about the constructor first.
In fact, telescoping constructor is a good method, which is easy to write and call. This method is also common when there are few parameters.
But the problem is that when there are many parameters (more and more), for example (it is difficult to find code that overlaps multiple parameters, so I will directly reference the code in this book here ):
public class NutritionFacts { private final int servingSize; // (mL) required private final int servings; // (per container) required private final int calories; // optional private final int fat; // (g) optional private final int sodium; // (mg) optional private final int carbohydrate; // (g) optional public NutritionFacts(int servingSize, int servings) { this(servingSize, servings, 0); } public NutritionFacts(int servingSize, int servings, int calories) { this(servingSize, servings, calories, 0); } public NutritionFacts(int servingSize, int servings, int calories, int fat) { this(servingSize, servings, calories, fat, 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, int carbohydrate) { this.servingSize = servingSize; this.servings = servings; this.calories = calories; this.fat = fat; this.sodium = sodium; this.carbohydrate = carbohydrate; }}
When I want to create an instance, the code will look like this:
public static void main(String[] args) { NutritionFacts cocaCola = new NutritionFacts(240, 8, 100, 0, 35, 27);}
To make the process of creating an instance clearer, we have another option-JavaBean mode.
I am not familiar with this yet, as shown below:
public class NutritionFacts { // Parameters initialized to default values (if any) private int servingSize = -1; private int servings = -1; private int calories = 0; private int fat = 0; private int sodium = 0; private int carbohydrate = 0; public NutritionFacts() { } // Setters 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; }}
Although there are several more steps to use than the one-row constructor, it is very clear:
public static void main(String[] args) { NutritionFacts cocaCola = new NutritionFacts(); cocaCola.setServingSize(240); cocaCola.setServings(8); cocaCola.setCalories(100); cocaCola.setSodium(35); cocaCola.setCarbohydrate(27);}
Compared to creating an instance using only one constructor, the constructor of the JavaBean mode instance is divided into several processes.
We may use this instance if the attributes are incomplete.
(<A JavaBean may be in a inconsistent state partway through its construction.>)
Of course, we can also do some operations to make it unusable when it is not completed, but I don't want to make a class more and more complex.
In addition, I cannot use the JavaBean mode to completely eliminate the possibility of designing classes as Immutable.
In this case, we chose to use Builder to solve this problem.
Example:
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 { // Required parameters private final int servingSize; private final int servings; // Optional parameters - initialized to default values private int calories = 0; private int fat = 0; private int carbohydrate = 0; private int sodium = 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 carbohydrate(int val) { carbohydrate = val; return this; } public Builder sodium(int val) { sodium = 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; }}
The call is very clear (the name parameter is simulated) and very simple:
public static void main(String[] args) { NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8) .calories(100).sodium(35).carbohydrate(27).build();}
Of course, Builder also has shortcomings.
Disadvantage 1. Create a Builder instance before creating an instance.
Disadvantage 2: The Builder mode is relatively lengthy.
However, when building an instance requires many steps (or many confusing parameters), the Builder mode is a good choice.
What is the Chinese version of objective JAVA?
The content is quite good, and the translation is quite good. I will not repeat it if many people complain about it on paper. however, it does not affect reading. It means that what you learn is not directed at paper. but then again ......
Valid Java (2nd Edition) Chinese Version
That's it ~