Builder Pattern
GoF
: Separate the construction of a complex object from its representation so that the same construction process can create different representations.Wiki
: The builder pattern is a design pattern designed to provide a flexible solution to various object creation problems in object-oriented programming. The intent of the Builder design pattern is to separate the construction of a complex object from its representationOther
: This a pattern people often use but rarely create of there own. This pattern deals with construction of Objects with lot of parameters and want to make the object once we are done constructing it.
Concepts
- Handles complex constructors
- Large number of parameters
- Immutability
- Examples:
- StringBuilder
- DocumentBuilder
- Locale.Builder
Design considerations
- Flexibility over telescoping constructors
- Generally implemented with static inner class
- Calls appropriate constructor
- Negates the need for exposed setters
- Java 1.5+ can take advantage of generics ***
Example/Demo
- Demonstrate exposed setters (LunchOrderBean.java / LunchOrderBeanDemo.java)
- Demonstrate Telescoping constructors (LunchOrderTelescopic.java / LunchOrderTelescopicDemo.java)
- Create Builder (LunchOrder.java / LunchOrderDemo.java)
- Build out example
Steps to create:
- Create a class which is supposed to have many fields and required immutable instance
- Decalre all fields as final, so that they can only be initialized in constructor
- Create a public static builder inner class
- Copy all the field declarations in the inner class without making them final (In case you make field inside inner class as final you have to initialize that in constructor else you will ahve compilation error)
- Create a public default constructor in Builder class (you can put any parameters here to make them mandatory)
- Now, create methods taking field type as input and returning complete instance after setting that. for examplepublic Builder bread(String bread) {this.bread = bread;return this;}
- Create a private constructor in Outer class that takes this Builder class and sets all the fields from the builder instance.private LunchOrder(Builder builder) {this.bread = builder.bread;this.condiments = builder.condiments;this.dressing = builder.dressing;this.meat = builder.meat;}
- Create a build method that will return the instance of Outer class. This is achieved by passing this builder instance to the outer class constructorpublic LunchOrder build() {return new LunchOrder(this);}
- You can test the above builder as:LunchOrder.Builder builder = new LunchOrder.Builder();builder.bread("bread").condiments("condiments").dressing("dressing").meat("meat");LunchOrder lunchOrder = builder.build();
- Done
Drawbacks
- Immutable objects are created
- Inner static class is generally used for implementation
- It is always Designed first
- Adds complexity, as people are not comfortable with object returning itself with each subsequent call
Contrast to other patterns
Builder | Prototype |
---|---|
Handles complex constructors | Implemented around a clone |
No interface required | Avoids calling complex constructors |
Can be a saperate class | NA |
Works with a legacy code | Difficult to implement in legacy code |
Summary
- Creative way to deal with complexity
- Easy to implement
- few drawbacks
- can refactor in with a saperate class (typically implemented with a static inner class)
Next
Explore the Generics version of builder pattern