Purpose
Builder
(creational pattern) separates the way of creationg object from their representation. Divides the object’s manufacturing process into stages. Each of the stages can be implemented in many ways, which allows creating different representations of objects of the same class. thanks to granting the principle of SRP
- single responsibility, OCP
- open / closed and DIP
- reversal of dependencies the change the way of creating objects is flexible and has a low cost. In addition, the code is easier to test, maintain, handle exceptions and prevent duplication. This pattern works on a similar basis to the construction plan. Director
as a responsible for the entire construction commissions to perform a specific job for a specific Builder
. As a result of the combination of their work, the final Product
is created. Speaking of the Builder
pattern, it is impossible to not mention its variation of the so-called Fluent Builder
. Its role is to create objects (with a lot of parameters) in a clear way by replacing the constructor.
Limitations
Using a pattern forces to create a specific Builder for each type of Product
. In addition, there is no guarantee of initialization of the class fields and Dependency Injection
may be difficult.
Usage
Builder
is used in the implementation of complex objects (composites
), which can be built in various ways, and their initialization is a multi-stage process. The use of the pattern avoids the creation of super class with extensive responsibility. It is used in initializing composites
in many external and internal libraries. In situations where the class builder has a long list of parameters (about 5), consider using Fluent Builder
.
Implementation
In the classic version of the pattern, object of Director
class orders the product (Product
) to the specific builder (ConcreteBuilder
) overseeing its work. Director
stores references to Builder
and during building the product, invokes individual operations on it. Each builder implements the common behavior of an abstract Builder
class or interface, creating a product in its own specific way. Builder
contains a reference to the product and returns it to the supervisor at the end of the work.
The following listing shows the implementations of the classic form Builder
.
The client uses the implemented pattern in the following manner.
In the Fluent Builder
version, the instance of Product
class is created by calling the Builder
static class. Using this way of creating objects, the initialization of all required fields and its order should be provided. The following listing shows the basic implementations of the pattern in the Fluent Builder
variant.
Thanks to such this approach, instead of creating an object by calling its constructor, its builder can be used.
Example
The application assists the staff of gastronomy chain in receiving and issuing orders. The Staff
service worker selects on the screen the dinner menus defined by the customer Meal
. The cooks Cook
with specializations of creating specific dish, receives list of orders to be processed. After preparing the meal, he passes it to service, and from there it goes to the customer. The following listing shows how to place orders using the Builder
.
In addition, the customer can compose his own set. For this purpose, the service worker selects the products manually. The following listing illustrates the implementation of manual creation of a set using Fluent Builder
.
The selection process for sets is as follows.
Libraries
Many external libraries such as: Retrofit
or system elements, eg: AlertDialog
, Notification
use the Builder
. However, to implement pattern there is no external libraries.