Combining a Utility classs functionality with the builder pattern, add some spicy properties to it, and here comes the utility-builder pattern. Utility classes are the container for lots of useful but lost code. Hard to find and hard to extend. The utility-builder (aka tool-builder) pattern provides relief. Lets try a definition…
The utility-builder pattern is characterized by providing the functionality of a utility class (or parts of it) being implemented with the means of the builder pattern, thereby moving configuration (and the like) concerns (otherwise passed to the utility class’s utility method) to the state of the utility-builder instance while providing a thread safe builder method for constructing the utility-builder’s concern which only takes those argument(s) being passed which are directly related to the concern of the utility-builder class and which must not be part of the state of the utility-builder’s instances.
… wow, what the heck do I mean?!? In terms of
software design patterns the
utility-builder pattern seems to belong to the
creational patterns as it borrows from the
builder pattern to replace the classic
utility class at least in some cases.
OK, this did not help very much? Then let’s go for the commonly accepted structure on describing
software design patterns:
The goal of the
utility-builder pattern is to provide an extensible and maintainable alternative for implementrating functionality otherwise being placed inside
utility classes. It also aims on transforming
utility classes’ functionality into an
API in terms of maintainability and extensibility. The
utility-builder pattern is to solve the problem of breaking an
API when extending
Also Known As
When filling up utility classes with functionality, some such
methods seem to be cluttered with
arguments to make the desired functionality really generic resulting in
telescoping methods. Which in turn makes the maintenance of such
methods error prone and their use tiresome:
Which arguments are mandatory? Which arguments are optional? Which are the best default values for optional arguments?
Sometimes utility classes end up with the same
method implemented various times with differing sets of
arguments passed. Just to cover any possible and impossible usage scenario.
“… the intention of the builder pattern is to find a solution to the
anti-patternoccurs when the increase of object
constructor parametercombination leads to an exponential list of
constructors… (see Builder pattern)
The utility-builder pattern applies the problem of
telescoping constructors to the problem of
telescoping methods common to utility classes.
Given the observation that
arguments of utility classes’s
methods often can be classified to be belonging either directly or indirectly to that
- The indirectly related
argumentsare pushed to the state of a utility-builder. Only the indirectly related
argumentsare represented as state of the utility-builder, being initialized with sound defaults in terms of convention over configuration whilst being modified as of the builder pattern.
- The directly related
methodexecuting (building) the utility-builder’s main concern. The directly related
argumentsdo not belong to the state of the utility-builder in order to enable
thread safeinvocation of the same instance of a utility-builder with varying directly related
A requirement arises to change the color palette to be used when printing out the ASCII art. The above method may be extended with an an additional
argument as follows:
Applying the utility-builder pattern to an AsciiArtBuilder, we solve the problem with the following software design:
Extending the above AsciiArtBuilder with new configuration properties (concern’s indirectly related arguments) does not break any API, the configuration properties are part of the state and do not need to be carried around by the code using the AsciiArtBuilder. The concern’s directly related arguments are passed to the actually executing (building)
side effects when being invoked by multiple
Director: The client using the UtilityBuilder
- UtilityBuilder: An interface defining the utility-builder’s functionality
ConcreteUtilityBuilder: A concrete implementation of the UtilityBuilder, there may be more than one implementation
UtilityProduct: The result of the process (build) functionality when invoking the UtilityBuilder
Directorinstantiates an implementation of choice of the UtilityBuilder such as the
Directorcan switch to another implementation as its business logic is coupled to the UtilityBuilder interface and not to a concrete implementation.
- Then the
Directormay changes the state of the UtilityBuilder as required by calling
withProperty( ... )and
withAntoherProperty( ... ), as of sound initial state, this step may be skipped.
build-utility’s process (build) functionality by invoking the
buildUtilityConcern( ... )method on the provided
argumentwith regard to its state.
As a utility-builder implements one specific functionality, it is easily maintained and extended without resulting in hundreds of lines of complex code and dozens of
telescoping methods common to utility class. Extending a utility-builder with new functionality does not break the
API as you would do by extending a
method of a utility class with additional arguments.
As a utility-builder provides means to execute its main concern without changing the utility-builder’s state, a utility-builder is thread safe as long as the configuration of the utility-builder is not changed. Changing the configuration still bears a risk for side effects as they are representing state.
When regarding the aspects mentioned above then the creation of utility-builder instances should stay low in case you do not need to invoke its functionality with ever changing configuration properties.
Readability and usability
For a utility class with
telescoping methods one has to remember all the configuration parameters somewhere in the code in order to invoke the utility class methods over and over again. This can bloat the code and make it unreadable and hard to focus on the actual task to be performed by the code. A utility-builder encapsulates these configuration parameters for you.
A utility-builder can be easily found with the type search of a modern
IDE as one utility-builder implements one specific functionality and as its name reflects its functionality.
Sticking to the
ASCII art example, consider an AsciiArtBuilder which can be used to print out text with a given
font rendered by using
ASCII characters (and the like) instead of color pixels when printing the banner (see Good bye utility classes, here come builders (part 2). See this banner for an example printing the text
DONT'T PANIC in
The utility-builder is defined by the AsciiArtBuilder
interface, a default implementation is represented by the
Concern’s indirectly related arguments
The implementation of the utility-builder pattern moves the configuration
arguments (aka the concern’s indirectly related
arguments) to the state of the AsciiArtBuilder implementation. This results in the according
methods look as follows:
Concern’s directly related arguments
The concern’s directly related arguments are passed to the executing (building)
method of the AsciiArtBuilder, here it is the text to be printed as
Using the AsciiArtBuilder may look as follows:
- Good bye utility classes, here come builders (part 1)
- Good bye utility classes, here come builders (part 2)
- Base! How low can you go? Base64, Base63, Base62, …