In this post, We will talk and learn about the Builder Pattern in Java.
There are mainly three major problems with Factory and Abstract Factory design patterns when the Object contains a lot of attributes.
- We have to pass too many arguments from the client program to the Factory class that can be error-prone because most of the time, the type(Data Type) of arguments is the same and from client-side it’s hard to maintain the order of the arguments.
- Few of the parameters might be optional but in the Factory pattern, we are forced to send all the parameters and optional parameters need to send as NULL or default value.
- If the object is very heavy and Object creation is complex, then all that complexity will be part of Factory classes that is confusing
Builder Design Pattern Example in JDK:
- java.lang.StringBuilder append() method
- java.lang.StringBuffer append() method
- All implementations of java.lang.Appendable(BufferedWriter,
CharArrayWriter, FileWriter, FilterWriter, OutputStreamWriter PipedWriter, PrintStream,
PrintWriter, StringWriter, Writer) are in fact good examples of the use of a Builder pattern in java. - java.nio.ByteBuffer#put() (also on CharBuffer, ShortBuffer, IntBuffer, LongBuffer, FloatBuffer, and DoubleBuffer)
- java.util.stream.Stream.Builder
Below is the complete source code:
Laptop.java
Code easily can be understood by reading provided java documentation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
package com.kkjavatutorials.builder; /** * Creating Laptop Object using Builder design Pattern * @author KK JavaTutorials */ public class Laptop { //Required Fields private String ram; private String hdd; private String cpu; //Optional Fields private boolean isGraphicsEnable; private boolean isBluetoothEnable; public String getRam() { return ram; } public String getHdd() { return hdd; } public String getCpu() { return cpu; } public boolean isGraphicsEnable() { return isGraphicsEnable; } public boolean isBluetoothEnable() { return isBluetoothEnable; } /*Make private constructor of Laptop(outer class) * so that direct object creation can be prevented * and Object can be created only by calling *LaptopBuilder:build() *Initialize all instance variables of *Laptop(outer class) from LaptopBuilder */ private Laptop(LaptopBuilder builder) { this.ram = builder.ram; this.hdd = builder.hdd; this.cpu = builder.cpu; this.isBluetoothEnable = builder.isBluetoothEnable; this.isGraphicsEnable = builder.isGraphicsEnable; } /** * Internal class LaptopBuilder, which has * public constructor to initializes required/Mandatory fields * and we have setter methods for all Optional fields * which returns LaptopBuilder itself. * @author KK JavaTutorials */ public static class LaptopBuilder{ //Required Fields private String ram; private String hdd; private String cpu; //Optional Fields private boolean isGraphicsEnable; private boolean isBluetoothEnable; public LaptopBuilder(String ram, String hdd, String cpu) { super(); this.ram = ram; this.hdd = hdd; this.cpu = cpu; } public LaptopBuilder setGraphicsEnable(boolean isGraphicsEnable) { this.isGraphicsEnable = isGraphicsEnable; return this; } public LaptopBuilder setBluetoothEnable(boolean isBluetoothEnable) { this.isBluetoothEnable = isBluetoothEnable; return this; } /*Only one way to create Laptop Object * by calling LaptopBuilder:build() */ public Laptop build() { return new Laptop(this); } } @Override public String toString() { return "Laptop [ram=" + ram + ", hdd=" + hdd + ", cpu=" + cpu + ", isGraphicsEnable=" + isGraphicsEnable + ", isBluetoothEnable=" + isBluetoothEnable + "]"; } } |
Finally, We have a client program Test.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
package com.kkjavatutorials.builder.client; import com.kkjavatutorials.builder.Laptop; /** * * @author KK JavaTutorials *Client program which uses Builder pattern to create Laptop object */ public class Test { public static void main(String[] args) { //Create Laptop with Required Fields Laptop laptop1 = new Laptop.LaptopBuilder("16 GB", "240 GB", "2.56 HZ").build(); System.out.println("Laptop Config::"+laptop1); //Create Laptop with Required and Optional Fields Laptop laptop2 = new Laptop.LaptopBuilder("32 GB", "1024 GB", "2.56 HZ").setBluetoothEnable(true).setGraphicsEnable(false).build(); System.out.println("Laptop Config::"+laptop2); //Create Laptop with Required and Optional Fields Laptop laptop3 = new Laptop.LaptopBuilder("32 GB", "240 GB", "2.56 HZ").setBluetoothEnable(true).build(); System.out.println("Laptop Config::"+laptop3); } } |
Output of this Client Program:
Laptop Config::Laptop [ram=16 GB, hdd=240 GB, cpu=2.56 HZ, isGraphicsEnable=false, isBluetoothEnable=false]
Laptop Config::Laptop [ram=32 GB, hdd=1024 GB, cpu=2.56 HZ, isGraphicsEnable=false, isBluetoothEnable=true]
Laptop Config::Laptop [ram=32 GB, hdd=240 GB, cpu=2.56 HZ, isGraphicsEnable=false, isBluetoothEnable=true]
You May Also Like:
Singleton Design Pattern in java
Prototype Pattern in Java
Factory Pattern in Java
Abstract Factory Pattern in Java
That’s all about the Builder Pattern in Java.
If you have any feedback or suggestion please feel free to drop in below comment box.