Fluent testing with the builder pattern
by Eing Ong
I've been asked repeatedly - what are fluent APIs and how does it relate to the builder pattern.
These are good questions and instead of just sending a link or two, here's a blog about it.
These are good questions and instead of just sending a link or two, here's a blog about it.
First, what is Fluent API or interface?
"Fluent interface (as first coined by Eric Evans and Martin Fowler) is an implementation of an object oriented
API that aims to provide for more readable code. A fluent interface is normally implemented by using method
cascading (concretely method chaining) to relay the instruction context of a subsequent call."
This highlights two important characteristics of a fluent API - readability and method chaining. Here's an
example from Gang of Four "Design Patterns: Elements of Reusable OO Software" -
API that aims to provide for more readable code. A fluent interface is normally implemented by using method
cascading (concretely method chaining) to relay the instruction context of a subsequent call."
This highlights two important characteristics of a fluent API - readability and method chaining. Here's an
example from Gang of Four "Design Patterns: Elements of Reusable OO Software" -
The examples above are chaining methods to build or construct an object. This actually ties two concepts
together. When fluent API is used for building an object, it is implementing the builder pattern.
What is the builder pattern?
"The builder pattern is a design pattern that allows for the step-by-step creation of complex objects usingthe correct sequence of actions. The construction is controlled by a director object that only needs to know
the type of object it is to create." -- GoF
"Builder pattern separates the construction of a complex object from its representation. This has the
immediate effect of making a complex target class simpler. It lets a builder class focus on the proper
construction of an object, leaving the target class to focus on the operation of a valid instance. This is
especially useful when you want to ensure the validity of an object before instantiating it and don’t want
the associated logic to appear in the target class’s constructors. A builder also accommodates step-by-step
construction, which often occurs when you create an object by parsing text." -- Design Patterns in Java
Hence, fluent testing with builder pattern is particularly useful when we have to construct a complex object.
This also allows you to write better code as you will be addressing the following when designing the
construction of the object (see Petri K's blog for more details) -
- Identifying the properties that cannot be updated after the object is created by making them final.
- Identifying the properties that can be updated after creation and the best way to update them.
When you're done, you should see these characteristics of a builder pattern
- Constructor of the object is private
- Creation of the object is via its builder static class
- The builder has mandatory parameters in its constructor
- The builder has setters for any optional parameters
- The builder has the responsibility to check for invalid data
- Object immutability is easily supported with final attributes and only public getters for these attributes
- You have created a readable DSL for building your complex object
Finally, here's an example from Effective Java, which demonstrates all the characteristics
of the builder pattern listed above -
Subscribe via RSS