问题
According to the book Design Patterns: Elements of Reusable Object-Oriented Software,:
The Builder Pattern separates the construction of a complex object from its representation so that the same construction process can create different representations.
In general the Builder pattern solves the issue with large number of optional parameters and inconsistent state by providing a way to build the object step-by-step and provide a method that will actually return the final Object.
With the builder pattern we go to have a build method to generate an object witch is immutable.
My Question:
Can I use the builder pattern keeping setters methods in the Class of the generate object, allowing the possibility to mutate the built object ?
If I go to produce mutable objects, I shouldn't use the builder pattern ?
回答1:
There is value in the Builder Pattern than goes beyond just helping to solve the telescoping parameter problem.
- They can make an API easier to use by clients since the setter methods are self-naming and, therefore, easier to remember.
- The Builder Pattern enables optional parameters, something that is offered with telescoping constructors only by using potentially awkward overloading.
- Client code that uses builders can be more self-documenting than code that uses constructors, enabling client code to be easier (and cheaper) to maintain
- The Builder Pattern can reduce bugs. Large lists of identically typed parameters can be accidentally transposed with telescoping constructors. In such a case, the compiler won't report the error and the resulting bugs can be far removed and hard to track down.
- Mandatory parameters for objects can be specified in the constructor signature for the Builder. The compiler will insist that these mandatory parameters are always provided at compile time.
- Useful APIs evolve over time; it is easy to add setter methods to a builder object, while it can be less easy and more error-prone to manage a set of overloaded constructors.
- The Builder Pattern is concurrency friendly. It is relatively straightforward to keep the mutable builder object thread confined and, therefore, threadsafe.
Builders are especially useful for constructing immutable objects because, for such objects, all the data must be supplied at build time. When there is a large amount of data to supply or when multiple steps must be completed, the Builder Pattern is pretty easy to recommend.
There is no rule that builder objects can't build mutable objects, however for mutable objects the JavaBeans pattern provides the same benefits (easy readability, self-documentation, reduced error prone-ness) with less code.
回答2:
The Builder Pattern is meant to replace what are called telescoping constructors (with a nod to @scottb) for optional parameters and not much else. It does not require the object to be immutable.
Also the builder should generally only include the attributes that matter at construction (a.k.a. build) time, hence the name builder. It should not include attributes that change over the life of the object but don't really matter after construction.
Conceptually, if you have a builder for Child
, the only 3 things that will matter are the mom
, the dad
and childGenes
(boy/girl, other genetic material). The height or weight of the child should not be a part of the builder as it will be driven partially by genes but will constantly change by factors beyond those present at birth (or "build" time).
That said, unless you really need it, it's best to have the object immutable.
Hope that helps!
来源:https://stackoverflow.com/questions/32854389/is-there-a-convention-that-objects-created-using-the-builder-pattern-be-immutabl