Problem, in the face of a problem with multiple parameters for a constructor, the existing practice is to use overlapping constructors in the way that the problem exists:
public class Nutritionfacts {private final int servingsize;//(ML) required private final int servings;//(per Co Ntainer) 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, cal Ories, fat, 0); } public nutritionfacts (int servingsize, int. servings, int calories, int fat, int sodium) {This (Ser Vingsize, 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; } public static void Main (string[] args) {nutritionfacts CocaCola = new Nutritionfacts (240, 8, 100, 0, 35, 27); }}
The problem with overlapping constructors is that clients using the Nutritionfacts class are prone to error and difficult, and the difficulty is that the client remembers the meaning and order of each parameter of the constructor. This way, the readability is also poor, the reason is that to read a code, it is necessary to remember the meaning of all the parameters used by the constructor.
--------------------------------------------------------------------------------------------------------------- ----------------------------------------------
An alternative solution:
public class Nutritionfacts {//Parameters initialized to default values (if any) private int servingsize =-1;// Required; No default value 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; } 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); }}
using the JavaBean method, create the object using the constructor of the empty argument, and then put the constructor parameters into the setter methods to implement, as above. the problems that exist, the construction process, are divided into several invocations. The above code block cannot be split to execute, and if split executes, it will cause the created object state to be inconsistent. the problem is that it causes the created object to be inconsistent in its state. This will appear in multithreaded programs. For example, Cocacola.setsodium (35); Before executing this code, the object CocaCola has already been used by other threads, which results in the use of a CocaCola object that is not in the correct state. simply put, the object is created, and the code that sets the state of the object is not atomized. ----------------------------------------------------------------------------------------------------------- -
Another workaround: Builder mode
public static void Main (string[] args) { nutritionfacts CocaCola = new Nutritionfacts.builder (8) . Calories ( ). Sodium (35). Carbohydrate. Build (); }
Contrast:
overlapping constructor mode
public static void Main (string[] args) { nutritionfacts CocaCola = new Nutritionfacts (8, 0, +); }
JavaBean Way
public static void Main (string[] args) { nutritionfacts CocaCola = new Nutritionfacts (); Cocacola.setservingsize (+); Cocacola.setservings (8); Cocacola.setcalories (+); Cocacola.setsodium (+); Cocacola.setcarbohydrate (); }
Builder mode, when the client is in use, it is necessary to remember the meaning and order of the two required parameters, and then, if additional optional construction parameters are required, they are implemented by calling the corresponding method. For example, if an optional parameter calories is required, the calories (int val) method is called. This readability is good, the user by reading the name of the method to know the meaning of the parameter, knowing that the constructor parameters passed at this time is used to set the value of the calories. this solves the problem of overlapping constructors, where readability is poor, and client programmers use error-prone problems. In addition, when you create an object by using the builder mode, the code executes at the same time, rather than dividing it into individual statements, which are separate statements instead of multiple statements. Builder Mode:
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 to 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; } public static void Main (string[] args) {nutritionfacts CocaCola = new Nutritionfacts.builder (240, 8) . Calories (+). Sodium (+). Carbohydrate (). build (); }}
Item 2---when encountering a constructor with multiple parameters, consider using the builder; Builder mode