What is the difference between the original Builder pattern by GoF and the "revised GoF Builder pattern" by Joshua Bloch?
2 Answers
The GoF pattern focuses on abstracting the steps of construction so that by varying the builder you can get different results while the "revised builder" is targeting the problem of unnecessary complexity added by multiple constructors. So the GoF pattern is more about abstraction and the revised patter is more about simplicity (IMO).
Look at the examples in http://en.wikipedia.org/wiki/Builder_pattern and http://rwhansen.blogspot.com/2007/07/theres-builder-pattern-that-joshua.html and it should be quite clear.

- 1,495
- 10
- 8
Note re Mikko's answer: Hansen's example has a few problems -- or, at least, differences from Bloch's version, though I'm of the opinion Bloch's version is superior.
Specifically:
First, Widget
's fields are set in Builder.build()
rather than in the Widget
constructor, and therefore aren't (and can't be) final
. Widget
is said to be immutable, but there's nothing to discourage another programmer from coming along and adding setters later.
Second, comments in Hansen's build method say "pre-creation validation goes here". Bloch (EJ 2ed. p.15) says:
It is critical that [the invariants] be checked after copying the parameters from the builder to the object, and that they be checked on the object fields rather than the builder fields (Item 39).
If you flip to Item 39 (p. 185) you see the reasoning:
[This] protects the class against changes to the parameters from another thread during the "window of vulnerability" between the time the parameters are checked and the time they are copied.
The fields in Widget
are immutable and don't require any defensive copying, but nonetheless it's safer just to stick to the correct pattern, in case someone comes along and adds a Date
or an array or some mutable Collection
later. (It also protects against another thread modifying the Builder
in the middle of a call to build()
, but that's a pretty narrow window of safety so it's probably best just to make sure Builder
s aren't shared between threads.)
A more Blochlike version would be:
public class Widget {
public static class Builder {
private String name;
private String model;
private String serialNumber;
private double price;
private String manufacturer;
public Builder( String name, double price ) {
this.name = name;
this.price = price;
}
public Widget build() {
Widget result = new Widget(this);
// *Post*-creation validation here
return result;
}
public Builder manufacturer( String value ) {
this.manufacturer = value;
return this;
}
public Builder serialNumber( String value ) {
this.serialNumber = value;
return this;
}
public Builder model( String value ) {
this.model = value;
return this;
}
}
private final String name;
private final String model;
private final String serialNumber;
private final double price;
private final String manufacturer;
/**
* Creates an immutable widget instance.
*/
private Widget( Builder b ) {
this.name = b.name;
this.price = b.price;
this.model = b.model;
this.serialNumber = b.serialNumber;
this.manufacturer = b.manufacturer;
}
// ... etc. ...
}
All Widget
fields are now final
, and all are validated after construction.

- 1
- 1

- 48,006
- 27
- 136
- 235
-
Wouldn't your example allow to create some instance of Builder with bogus (or missing, unstable) properties and then call "new Widget (myBogusBuilder)" and end up with an "unstable" instance of Widget? (eg, not validating that price must be at least more than "1", since you'd only check that in the build() method) – Rafa Jun 18 '12 at 19:56
-
It would if the Widget constructor was public, but it's private. The only way to call it (from outside the class) is via build(). – David Moles Jun 19 '12 at 21:38
-
1oh, true; didn't notice that (gonna review my glasses...). thanks :) – Rafa Jun 20 '12 at 14:57
-
Problem with this approach is that you need to define all the members twice, once in the builder and once in the actual class. http://stackoverflow.com/a/1632099/131929 shows how this can be avoided. With that other approach, however, you cannot have final members although the object itself is still immutable. – Marcel Stör Jun 07 '13 at 06:26
-
I don't know, I'm not a fan of that approach -- the builder's not reusable, it's not thread-safe, and you can't design the build product class to guarantee it's fully initialized at construction. If I was really worried about DRY, I'd probably use an immutable (copy-on-write) builder and make the last builder instance double as the build product's immutable data. – David Moles Jun 07 '13 at 16:07
-
1Immutable Builder version here: http://showyourwork.chrononaut.org/2013/06/07/favor-immutability/#immutable-builder – David Moles Jun 07 '13 at 17:30