Builder Design Pattern in Java
Builder pattern was introduced to solve some of the problems with Factory and Abstract Factory design patterns when the Object contains a lot of attributes.
There are three major issues with Factory and Abstract Factory design patterns when the Object contains a lot of attributes.
- Too Many arguments to pass from client program to the Factory class that can be error prone because most of the time, the type of arguments are same and from client side its hard to maintain the order of the argument.
- Some of the parameters might be optional but in Factory pattern, we are forced to send all the parameters and optional parameters need to send as NULL.
- If the object is heavy and its creation is complex, then all that complexity will be part of Factory classes that is confusing.
Example – Entity Class (Phone.java)
class Phone { protected String model; protected int frontCamera; protected int backCamera; protected int battery; protected String ram; protected float price; protected int storage; @Override public String toString() { return "Phone [model=" + model + ", frontCamera=" + frontCamera + ", backCamera=" + backCamera + ", battery=" + battery + ", ram=" + ram + ", price=" + price + ", storage=" + storage + "]"; } }
Builder Helper Class (PhoneBuilder.java)
class PhoneBuilder extends Phone { public PhoneBuilder setModel(String model) { this.model = model; return this; } public PhoneBuilder setFrontCamera(int frontCamera) { this.frontCamera = frontCamera; return this; } public PhoneBuilder setBackCamera(int backCamera) { this.backCamera = backCamera; return this; } public PhoneBuilder setBattery(int battery) { this.battery = battery; return this; } public PhoneBuilder setRam(String ram) { this.ram = ram; return this; } public PhoneBuilder setPrice(float price) { this.price = price; return this; } public PhoneBuilder setStorage(int storage) { this.storage = storage; return this; } public PhoneBuilder build() { return this; } }
Main Method class – object creation (BuilderPattern)
import java.util.HashMap; import java.util.Map; public class BuilderPattern { public static void main(String[] args) { // With constructors all the parameters are required, if default is to be supplied, then we have to mention each // time those default values /* * Phone nokia1100 = new Phone("Nokia 1100", 13, 20, 4000, "2 GB", 1100.00f, 4); * Phone nokia1110 = new Phone("Nokia 1100", 13, 20, 4000, "2 GB", 1100.00f, 4); */ Phone ph1 = new PhoneBuilder().setModel("Nokia 1100").build(); System.out.println(ph1.toString()); Phone ph2 = new PhoneBuilder().setModel("Nokia 1110").setBattery(4000).build(); System.out.println(ph2.toString()); Phone ph3 = new PhoneBuilder().setModel("Nokia 1600").setBattery(4000).setFrontCamera(13).setBackCamera(20) .build(); System.out.println(ph3.toString()); HashMap<String, Map> hash_map = new HashMap<String, Map>(); Map<String, Integer> hm = new HashMap<String, Integer>(); hm.put("field1", 10); hash_map.put("0", hm); hm.put("field2", 20); hash_map.put("1", hm); } }