CHAPTER 2
CREATING AND DESTROYING OBJECTS
16
Note that the
build
method in each subclass’s builder is declared to return the
correct subclass: the
build
method of
NyPizza.Builder
returns
NyPizza
, while
the one in
Calzone.Builder
returns
Calzone
. This technique, wherein a subclass
method is declared to return a subtype of the return type declared in the super-
class, is known as
covariant return typing
. It allows clients to use these builders
without the need for casting.
The client code for these “hierarchical builders” is essentially identical to the
code for the simple
NutritionFacts
builder. The example client code shown next
assumes static imports on enum constants for brevity:
NyPizza pizza = new NyPizza.Builder(SMALL)
.addTopping(SAUSAGE).addTopping(ONION).build();
Calzone calzone = new Calzone.Builder()
.addTopping(HAM).sauceInside().build();
A minor advantage of builders over constructors is that builders can have mul-
tiple varargs parameters because each parameter is specified in its own method.
Alternatively, builders can aggregate the parameters passed into multiple calls to a
method into a single field, as demonstrated in the
addTopping
method earlier.
The Builder pattern is quite flexible. A single builder can be used repeatedly
to build multiple objects. The parameters of the builder can be tweaked between
invocations of the
build
method to vary the objects that are created. A builder can
fill in some fields automatically upon object creation, such as a serial number that
increases each time an object is created.
The Builder pattern has disadvantages as well. In order to create an object, you
must first create its builder. While the cost of creating this builder is unlikely to be
noticeable in practice, it could be a problem in performance-critical situations.
Also, the Builder pattern is more verbose than the telescoping constructor pattern,
so it should be used only if there are enough parameters to make it worthwhile, say
four or more. But keep in mind that you may want to add more parameters in the
future. But if you start out with constructors or static factories and switch to a
builder when the class evolves to the point where the number of parameters gets
out of hand, the obsolete constructors or static factories will stick out like a sore
thumb. Therefore, it’s often better to start with a builder in the first place.
In summary,
Do'stlaringiz bilan baham: