For a given class, The more complex its construction, the more you need builders. Builders is probably the solution when you have the most complicated object construction logic. If builder can’t handle it then nothing else can.
Example 1: My quant object ForwardCurve construction takes a lot of inputs including yield curve, repo curve, dividend collection, dividend blending … Each of these inputs are non-trivial quant objects, so it’s sometimes cumbersome to pass all of them into a forwardCurve constructor. As an alternative, we use a builder class to _gather_ the inputs and then call myFwdBuilder.constructCurve().
Optional inputs with default values — (supported in c++ but) not supported in java constructors. Therefore, with 3 optional inputs you may need 8 constructors! With a nested builder class, we need just one, private, simple constructor.
Builder can even use a recursive algorithm.
Prepare, prepare, prepare, build — the last build() is quick and exception-safe. The complexity and error handling is all extracted into the builder class.
With this builder, we have the flexibility to call myFwdBuilder.getCurve() any number of time.
We can also query the builder to get attributes that we can’t put into the final product i.e. the constructed ForwardCurve object. For example, the raw dividend input data should not be part of the fwd object. They are digested, then absorbed into the fwd curve in “digested” form.
Note one builder instance holds one curve + all the building materials for that one curve.
With a builder, all the
fields can be public final.
Example 2: The Libor yield curve construction takes at least 3 series of rates (ED deposits, ED futures, swaps). So we use builders to manage the complex construction.
Example 3: The volatility object construction is even more complex.