In this short post, I describe and name a cousin of the builder pattern — builder lite.
Unlike a traditional builder, which uses a separate builder object, builder lite re-uses the object itself to provide builder functionality.
Here’s an illustrative example
In contrast, the full builder is significantly wordier at the definition site, and requires a couple of extra invocations at the call site:
The primary benefit of builder-lite is that it is an incremental, zero-cost evolution from the new method.
As such, it is especially useful in the context where the code evolves rapidly, in an uncertain direction.
That is, when building applications rather than library.
To pull a motivational example from work, we had the following typical code:
Here’s a new method with a whole bunch of arguments for various dependencies.
What we needed to do is to add yet another dependency, so that it could be overwritten in tests.
The first attempt just added one more parameter to the new method:
However, this change required update of the seven call-sites where the new was called to supply the default counter.
Switching that to builder lite allowed us to only modify a single call-site where we cared to override the counter.
A note on naming:
If builder methods are to be used only occasionally, with_foo is the best naming.
If most call-sites make use of builder methods, just .foo might work better.
For boolean properties, sometimes it makes sense to have both: