Java Builder Design Pattern Example
1. Introduction
In this article, we will describe Java Builder Design Pattern in detail. The Builder design pattern, as its name suggests, seems to be an alternative way to develop complex objects. This can only be used if you choose to create different unchangeable objects who use the same process of object building.
This design pattern in Java is a type of Creational design pattern and it is used to create objects, similar to the Factory design pattern, which is also a Creational design pattern. In simple words, Builder design pattern is a creational design pattern it means its solves the problem related to creation of object.
You can also check a tutorial in the following video:
In java, Constructors are used to create object and can use the required parameters to create objects. Problem begins whenever an object can also be created with many parameters, some of which may be compulsory and others optional. For understanding, consider a class used to make Juice, we now require a number of items such as water, fruit, mixer, ice, straw to make Juice. Most are compulsory but some of them are optional, such as ice, straw, etc. But if we have overloaded constructor for different kind of juice then there would be more than one constructor and even worst they will accept a lot of parameter. This problem id solved by using Builder design pattern. Builder design pattern not only enhances readability but also reduces the risk of error by explicitly adding flavours and trying to make the object accessible once it has been fully created.
2. Java Design Patterns
Java design patterns were categorised further into three crucial and popularly used sub – groups that are explored below.
2.1 Creational Pattern
In object creation, creational design patterns takes place. They render the creation process much more efficient and creative. Creative patterns in particular can deliver a wide range of choices as to which objects are produced, how all these objects are produced and how they are initialised. This pattern can sometimes be labelled into either class and even object creation patterns. Although class-creation patterns effectively use inheritance in the installation process, where object-creation patterns effectively use high – level delegation to get all the job done properly. The creational design patterns are also split into six different design pattern types.
2.2 Structural Pattern
Structural pattern design characterises seven different types of design patterns. Structural design patterns are design patterns which optimise design by identifying a quick and easy way of conveying relationships between the objects. Such design patterns focus heavily upon how classes and objects could be linked to form larger frameworks. The structural design patterns try to simplify or promote the structure by understanding the difference between the structural elements.
2.3 Behavioural Pattern
These design patterns actually relate to the class-to-object communication. Behavioural design patterns are some patterns which affect communication between objects most specifically. This pattern characterises eleven different pattern classifications for interaction among objects. These design patterns are being used to deal with object algorithms, relationships and responsibilities.
In this article we will explore one of the commonly used Creational design pattern–the Builder design pattern. This article describes the idea of the Builder design pattern with a real – life example to give you a complete understanding of how well the Builder design pattern allows software developers to provide a better application. The following section develop this pattern to analyse every portion of the Builder design pattern. Furthermore, we will implement the Builder design pattern into Java program.
3. Understanding the Builder design pattern
The builder design pattern, as its name suggests, is an alternative way to build complex objects. It can only be used if you really want to create different unchangeable objects who use the same mechanism of object building. In other words, Builder design pattern allows for object level access control by acting as a pass through entity or a placeholder object. The objective of the Builder design pattern is to isolate a complicated object from its own representation. So that different representation can develop the same construction process.
The Builder design pattern is designed to ” isolate the development of a complicated object from its own representation so that different representations can be produced by the very same construction process. ” It is used to build a complex object step by step and thus the final step is returned. The process of building an object ought to be mundane, such that different representations of the same object can be created.
This design pattern generally solves problems in object – oriented programming, that is which constructor to use while programming. We often write a lot of constructor and it’s really difficult to manage them. The multiple constructor with multiple parameter variations is called the telescopic constructor.
Let’s look at the UML class diagram before you go into more detail to understand the Builder design pattern.
The following classes, interfaces and objects are included in the UML Class Builder Design Pattern:
Product:
In the above diagramproduct
class defines the type of the sophisticated object that is to be created by the builder design pattern.Builder:
Builder
is an abstract class that defines all moves needed to create aproduct
properly. Each and every move seems to be usually abstract, since the real function of thebuilder
class in the concrete sub classes is actually carried out. To return the final product, theGetResult()
method is used. Theconstructing
class is sometimes overtaken by a simple interface.ConcreteBuilder:
A number ofconcrete builder
classes are inherited from theBuilder
class are seen in the above diagram. The functionality of such classes would be to develop a particular complicatedproduct
.Director:
In the diagramdirector
class monitors the algorithm that produces the finalproduct
. A object indirector
class as well as itsconstruct()
method are called. Theconstruct()
method contains a parameter to grab the specificconcreteBuilder
object to produce theproduct
. Further the director class then calls theconcreteBuilder
methods to create theproduct
object in the correct order. When the process is completed, thebuilder
class object’sGetResult()
method may be used to return the product.
In simple words, the Builder
provides an interface to create the components of a product
class and ConcreteBuilder
class implements this interface. The ConcreteBuilder
class monitors the representation it produces, opens the way to acquire both the product and the construction of the product
. The Director
class builds the object via the Builder
interface. The generated product is the object, usually complicated, we build.
3.1 Real Life Example
Before implementing the Builder design pattern in java code, let us look at a real life example to better understand this design pattern. To understand, consider an example of food ordering at restaurant. In the below diagram we will explain Builder design pattern using this real world example for better understanding.
In the above example of food ordering customer is acting as a client class, cashier acting as a director class and restaurant crew are acting as a builder class. In the restaurant there are two types of meals are available such as veg meal and non veg meal. Veg meal consists of veg burger, fries, coke and toy car whereas Non veg meal consists of non veg pizza, fries, Pepsi and toy bike. Construction process for both the meal are same and it consists of five steps such as main item, side item, drink, toy and then pack. If suppose a customer went to the restaurant and orders a veg kid meal to the cashier. Cashier then forwards the order to the restaurant crew to complete the order. Now, restaurant crew first build the veg burger then they will build fries then coke and at last they build toy. After building all the meal restaurant crew now will pack the meal and forwards to the customer. So, here in this example veg kids meal is a complex object.
4. Implementing Builder design pattern
In this section, we will implement the Builder design pattern in java program using the real word example-Juice maker store. In Juice maker store the shopkeeper makes different types of fruit and vegetable juices according to customer’s order. Suppose if a customer orders an orange juice then the shopkeeper takes three or four oranges, water, sugar, ice cubes etc. as an ingredients and grinds all these ingredients in a juicer and serve to the customer.
Juice.java
public class Juice { private int water; private int fruit; private int sugar; private int icecube; private String juicename; public int getWater() { return water; } public void setWater(int water) { this.water = water; } public int getFruit() { return fruit; } public void setFruit(int fruit) { this.fruit = fruit; } public int getSugar() { return sugar; } public void setSugar(int sugar) { this.sugar = sugar; } public int getIceCube() { return icecube; } public void setIceCube(int icecube) { this.icecube= icecube; } public String getJuiceName() { return juicename; } public void setJuiceName(String juicename) { this.juicename= juicename; } public String toString() { return "Cold" + juicename + "!!!! [" + water + " ml of water, " + fruit + "as a fruit, " + sugar + " gm of sugar, " + icecube + " ml of " + juicename + "]\n"; } }
In this above code we have created Juice
class in which we have declared five private variables namely water
, fruit
, sugar
, icecube
, juicename
. Also we have implemented set()
and get()
methods for this variables. For example, getwater()
and setWater()
methods.
JuiceMaker.java
public abstract class JuiceMaker { private Juice juice; public Juice getJuice() { return juice; } public void setJuice(Juice juice) { this.juice = juice; } public final Juice makeJuice() { Juice juice = createJuice(); setJuice(juice); setJuiceType(); setWater(); setFruit(); setSugar(); setIceCube(); return juice; } abstract void setJuiceType(); abstract void setWater(); abstract void setFruit(); abstract void setSugar(); abstract void setIceCube(); abstract Juice createJuice(); }
In the above code we have created an abstract class known as JuiceMaker
. In this abstract class we have declared Juice
class variable as juice
and implemented set()
and get()
methods for this variable. Also we have created template method that creates Juice
object and returns Juice
and we have defined several abstract methods such as setJuiceName()
, setWater()
, setFruit()
, setSugar()
, setIceCube()
, createJuice()
.
OrangeJuice.java
public class OrangeJuice extends JuiceMaker { Juice createJuice() { return new Juice(); } public void setWater() { System.out.println("Step 1 : Adding water into the juicer"); getJuice().setWater(40); } public void setFruit() { System.out.println("Step 2 : Adding fruit into the juicer"); getJuice().setFruit(4); } void setSugar() { System.out.println("Step 3 : Adding sugar into the juicer"); getJuice().setSugar(10); } void setIceCube() { System.out.println("Step 4 : Adding 5 to 6 numbers of ice cubes into the juicer"); getJuice().setIceCube(6); } void setJuiceType() { System.out.println("orange"); getJuice().setJuiceName("orange"); } }
In the above code we have created OrangeJuice
class which extends JuiceMaker
abstract class. In this class we implemented the abstract classes that are defined in the JuiceMaker
class. For example, setWater()
, setFruit()
, setSugar()
, setIceCube()
, setJuiceType()
.
AppleJuice.java
public class AppleJuice extends JuiceMaker { Juice createJuice() { return new Juice(); } public void setWater() { System.out.println("Step 1 : Adding water into the juicer"); getJuice().setWater(50); } public void setFruit() { System.out.println("Step 2 : Adding fruit into the juicer"); getJuice().setFruit(6); } void setSugar() { System.out.println("Step 3 : Adding sugar into the juicer"); getJuice().setSugar(20); } void setIceCube() { System.out.println("Step 4 : Adding 7 to 8 numbers of ice cubes into the juicer"); getJuice().setIceCube(8); } void setJuiceType() { System.out.println("apple"); getJuice().setJuiceName("apple"); } }
In the above code we have created AppleJuice
class which extends JuiceMaker
abstract class. In this class we implemented the abstract classes that are defined in the JuiceMaker
class. For example, setWater()
, setFruit()
, setSugar()
, setIceCube()
, setJuiceType()
.
ShopKeeper.java
public class ShopKeeper { public static Juice takeOrder(String juiceType) { JuiceMaker juiceMaker = null; if (juiceType.equalsIgnoreCase("orange")) { juiceMaker = new OrangeJuice(); } else if (juiceType.equalsIgnoreCase("apple")) { juiceMaker = new AppleJuice(); } else { System.out.println("Sorry we don't take order for " + juiceType); } return juiceMaker.makeJuice(); } }
In the above code we have created Shopkeeper
class in which we have implemented takeOrder()
method with one argument as juiceType
. In this method we defined that if customer orders orange juice then the shopkeeper will make orange juice. Similarly for apple juice order.
BuilderDesignPattern.java
public class BuilderDesignPattern { public static void main(String[] args) { Juice orange = ShopKeeper.takeOrder("orange"); System.out.println(orange); Juice apple = ShopKeeper.takeOrder("apple"); System.out.println(apple); } }
In the above code we have created BuilderDesignPattern
class in which we have implemented main()
method. Inside this main()
method we have created Juice
class object such as orange and apple and called takeOrder()
method of Shopkeeper
class.
5. Benefits of using Builder Design Pattern
In this article, already we have studied what the Builder design pattern is, its practical application using the java code, and also the understanding of the Builder design pattern class diagram and its real-world example. Now let’s start talking about its advantages.
- Main benefit of Builder design pattern is that it enables to decrease the number of parameters in the constructor, so that optional parameters do not need to be passed to the constructor.
- In this pattern the parameters for the constructor are limited and beautifully written method calls are offered.
- One of the main advantage of this pattern is object has always been fully instantiated.
- In this design pattern unchangeable objects can be constructed without too much complicated reasoning in the process of object construction.
6. Use of Builder Design Pattern
There are three common circumstances during which the Builder design pattern applies as follows:
- Builder design pattern is applicable when we have a “telescopic” constructor. The Builder pattern allows us to create objects gradually. In addition, we can always use the necessary steps and avoid the optional steps when we build a single object.
- Builder design pattern will be used to build totally different products using the same construction process. Each and every product is described by a separate constructor class. Building order control code can live in a single director class.
- Step by step, Builder design pattern builds products. This empowers deferred or indeed recursive construction, which is required when you work with tree structures. During construction steps, Builder doesn’t really reveal incomplete products. So This precludes corrupt results from client code.
7. Demerits of Builder Design Pattern
So in this segment we will understand some of the downsides of the Builder design pattern:
- The number of lines of program rises by at least double in the Builder design pattern, but in terms of design flexibility and so much more legible code the amount of effort pays off.
- Another disadvantage of Builder design pattern is it requires the creation of an independent ConcreteBuilder for each and every product type.
8. Java Builder Design Pattern – Conclusion
Thus it is concluded that the Builder design pattern is a nice solution, not just for model classes, but to every object with over three or four parameters. We can increase readability of our code with a bit of additional work. Design patterns are hailed as the best in practical terms, so that’s a great advantage if we understand most of them and Builder design pattern is a good to start with.
9. Download the Source Code
The above implemented java program can be downloaded from the below link.
You can download the full source code of this example here: BuilderDesignPattern.zip