The Builder Pattern
Reasoning
I won’t even go into why you should learn patterns. Patterns are canned knowledge!
A problem the Builder Pattern solve
It helps you avoid situations like:
p = new Product(“STK”, “XX”, “TSZ”, 10.0, 11.33, 12.0, 8.0, 6.66, “AA”, 33.4, 45.0);
With so many parameters, it’s easy to confuse the user of the method. Which one was the volatility now? Errors are hard to spot!
Implementation
public class Product { private String symbol; private String sectype; private String currency; private String exchange; /* The Builder class */ public static class Builder { private String symbol; private String sectype; private String currency; private String exchange; public Builder symbol(String n) { this.symbol = n; return this; } public Builder secType(String a) { this.secType = a; return this; } public Builder exchange(String a) { this.exchange = a; return this; } public Builder currency(String a) { this.currency = a; return this; } public Product build() { return new Product(name, address); } } // The regular constructor is now private private Product(String symbol, String sectype, String exchange, String currency) { this.symbol = symbol; this.sectype = sectype; this.exchange = exchange; this.currency = currency; } }
Creating a Product has now become very easy and natural:
Product p = new Product.Builder()
.name(“ERIC.B”)
.secType(“STK”)
.exchange(“NASDAQ”)
.currency(“USD”)
.build();
A lot better, right? Just remember the .build() call at the end!
How does it work?
Basically, you create setters (preferably you leave out the ‘set’ in the method name) in the Builder class (ProductBuilder in the example), but let the setters “return this”. That way, you can chain the calls. Neat huh!
You create a static Builder class which preferably is internal to the Product class. That way it has access to the private Product constructor.
The build() function then calls the Product private constructor.
There is a considerable cost to the Builder pattern in that one must essentially double the number of lines of code each attribute and for setting those attributes. This price pays off, however, since the client code benefits greatly in terms of usability and readability. The parameters to the constructor are reduced and are provided in highly readable method calls.
best of all: there is also no need to pass null values for optional parameters!
If you don’t like the Product.Builder() syntax you can have the Builder be an external class (and call it ProductBuilder), but then the Product constructor can’t be private anymore.
Conclusion
Generally speaking, you can see that the Builder pattern is used when you construct an object using chained setters, with a build() call ending the chain.