Static factories and constructors have one common limitation: they do not scale well to a large number of optional parameters.
When there are several required attributes and multiple optional attributes in a class, overlapping constructor mode, JavaBeans mode, or builder mode are used, but each has advantages and disadvantages.
When there are many parameters, the client code in the overlay constructor mode is difficult to write and is still more difficult to read.
The JavaBeans mode calls a parameterless constructor to create the object, and then calls the setter method to set each necessary parameter, as well as each dependent optional parameter. Because the construction process is divided into several invocations, JavaBean may be in an inconsistent state during construction. Another disadvantage associated with this is that the JavaBeans mode prevents the possibility of making classes immutable.
Instead of generating the desired object directly, the builder mode allows the client to invoke the constructor (or static factory) with all the necessary parameters, and then the client invokes a setter-like method on the builder object to set each relevant optional parameter. The client finally calls the no-argument build method to generate the immutable object. This builder is the static member class of the class it builds.
Here is an example of this:
1 Public classnutritionfacts {2 Private Final intservingsize;3 Private Final intservings;4 Private Final intcalories;5 Private Final intfat;6 Private Final intsodium;7 Private Final intcarbohydrate;8 9 Public Static classBuilder {Ten //Required Parameters One Private Final intservingsize; A Private Final intservings; - - //Optional parameters-initialized to default values the Private intCalories = 0; - Private intFat = 0; - Private intCarbohydrate = 0; - Private intSodium = 0; + - PublicBuilder (intServingsize,intservings) { + This. servingsize =servingsize; A This. servings =servings; at } - - PublicBuilder Calories (intval) { -Calories =Val; - return This; - } in PublicBuilder Fat (intval) { -Fat =Val; to return This; + } - PublicBuilder Carbohydrate (intval) { theCarbohydrate =Val; * return This; $ }Panax Notoginseng PublicBuilder Sodium (intval) { -Sodium =Val; the return This; + } A the Publicnutritionfacts Build () { + return NewNutritionfacts ( This); - } $ } $ - Privatenutritionfacts (Builder builder) { -Servingsize =builder.servingsize; theServings =builder.servings; -Calories =builder.calories;WuyiFat =Builder.fat; theSodium =Builder.sodium; -Carbohydrate =builder.carbohydrate; Wu } - About Public Static voidMain (string[] args) { $Nutritionfacts CocaCola =NewNutritionfacts.builder (240, 8). -Calories (sodium). Carbohydrate (27). Build (); - } -}
It checks the constraints as they are copied from the builder to the object, and examines them in the object domain instead of the builder domain. If any constraints are violated, the build method should throw illegalargumentexception. Another way to impose constraints on multiple parameters is to check all the parameters that a constraint must hold with multiple setter methods. Once an invalid argument is passed, the constraint fails immediately, rather than waiting for the build method to be called. The slight advantage of builder compared to constructors is that builder can have multiple mutable parameters. Constructors, like methods, can have only one mutable parameter.
The traditional abstract factory implementation in Java is a class object, and the Newinstance method always attempts to invoke the class's parameterless constructor, which may not even exist at all. The class.newinstance destroys the compile-time exception check. There is also a shortage of builder mode. In order to create an object, you must first create its builder. In a very performance-oriented situation, it may be problematic. The builder mode is also more verbose than the overlapping constructor pattern, so it is used only when there are many parameters, such as 4 or more parameters. It's usually best to start with the builder.
If you have multiple parameters in a class's constructor or static factory, the builder mode is a good choice when designing this class, especially if most of the parameters are optional. Client-side code that uses the builder mode is easier to read and write than using the traditional overlapping constructor pattern, and the builder is more secure than JavaBeans.
Resources
"Effective Java Chinese version 2nd edition" p9-13
Java "Effective Java Chinese version 2nd edition" Learning Note when you encounter multiple constructors, consider using the builder