There's a Builder pattern that Joshua Bloch has briefly described in a couple of his "Effective Java Reloaded" sessions at Java One. This Builder is not necessarily a replacement for the original design pattern. The problems this Builder pattern can solve are too many constructors, too many constructor parameters, and over use of setters to create an object.
Here are some examples of the pattern in use. These examples create various Widgets with two required properties and several optional ones -
Widget x = new Widget.Builder("1", 1.0).
model("1").build();
Widget y = new Widget.Builder("2", 2.0).
model("2").manufacturer("222").
serialNumber("12345").build();
Widget z = new Widget.Builder("3", 4.0).
manufacturer("333").
serialNumber("54321").build();
The basic idea behind the pattern is to limit the number of constructor parameters and avoid the use of setter methods. Constructors with too many parameters, especially optional ones, are ugly and hard to use. Multiple constructors for different modes are confusing. Setter methods add clutter and force an object to be mutable. Here is an class skeleton of the pattern -
public class Widget {
public static class Builder {
public Builder(String name, double price) { ... }
public Widget build() { ... }
public Builder manufacturer(String value) { ... }
public Builder serialNumber(String value) { ... }
public Builder model(String value) { ... }
}
private Widget(Builder builder) { ... }
}
Notice that Widget has no public constructor and no setters and that the only way to create a Widget is using the static inner class Widget.Builder. Widget.Builder has a constructor that takes the required properties of Widget. Widget's optional properties can be set using optional property methods on the Widget.Builder. The property methods of Widget.Builder return a reference to the builder so method calls can be chained.
A really nice feature of this pattern is the ability to do pre-creation validation of an object state. When setters are used to set object state during creation it is virtually impossible to guarantee that object has been properly created.
Here is the full source for Widget and its Builder -
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() {
// any pre-creation validation here
Widget result = new Widget(name, price);
result.model = model;
result.serialNumber = serialNumber;
result.manufacturer = manufacturer;
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 String name;
private String model;
private String serialNumber;
private double price;
private String manufacturer;
/**
* Creates an immutable widget instance.
*/
private Widget(String name, double price) {
this.name = name;
this.price = price;
}
public String toString() {
return super.toString() + " {"
+ "name="
+ getName()
+ " model="
+ getModel()
+ " serialNumber="
+ getSerialNumber()
+ " price="
+ getPrice()
+ " manufacturer="
+ getManufacturer()
+ "}";
}
public String getManufacturer() {
return manufacturer;
}
public String getModel() {
return model;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
public String getSerialNumber() {
return serialNumber;
}
}
Notice that Widget's private constructor takes the required properties and that the Builder sets the optional properties. Another thing to note is that widget is an immutable object as implemented.
64 comments:
Which JDK version did you use for this example? I can compile this example in JDK 1.5, but 1.4.2 complains about not finding the Builder constructor.
This is not a builder pattern.
this is a builder pattern http://en.wikipedia.org/wiki/Builder_pattern
Wow. That's a pretty nice design pattern. It could be extremely useful. However, it doesn't appear to be thread-safe. I think the fields of a static class like this could get modified by other threads want to do the same thing. It could be quite a surprise when executing build().
Maybe someone has a suggestion for making it safer, but I can't think of how.
It is threadsafe actually. The fact that you are invoking
"Widget x = new Widget.Builder("1", 1.0).model("1").build();"
implies that you are creating a new instance of the Widget.Builder every time
It is threadsafe actually. The fact that you are invoking
"Widget x = new Widget.Builder("1", 1.0).model("1").build();"
implies that you are creating a new instance of the Widget.Builder every time
you have a nice site. thanks for sharing this site. there are various kinds of ebooks are available here
http://feboook.blogspot.com
Really great ideas. I like every example. Just might have to try these...
more template
I decided to implement this for a JTextField Document builder throughout my application. Thanks for the tip! I've linked and referenced you at my programming blog, GlitchHound.
It is very good blog, i think this blog about software design development and so technical topic really i like it, thanks for information.
I agree with the Anonymous poster. I'm not sure how you see this as being thread safe until you call build method.
"static" does not have anything to do with not being threadsafe here. It is just keyword to define "static" inner class - that is class does not have reference to outer class. It is poor choice of keyword from this point of view, because it confuses people.
It "is" thread safe, because it is not expected you will pass instance of Builder to different thread - just create Widget and forget about it.
Notice all attributes of Builder are private and not static. Thus nobody can access them until build() is called and a Widget is constructed.
Let's split following example to its parts:
new Widget.Builder("1", 1.0). model("1").build();
1. new Widget.Builder("1", 1.0) creates an instance of Builder with initial data for name and price
2. instance.model("1") sets a new value into Builder instance
3. instance.build() creates widget.
4. the instance of Builder is lost
Thank you for the great info and also a nice design pattern.
This is great. Its repetitive in that the builder repeats the fields so using a base class for both Builder and built class helps. Here's an example that is less repetitive:
Sorry in advance about the formatting!
public class CellBase {
protected CellBase() {
}
protected String column = "UNKNOWN";
protected Integer row = -1;
protected String value;
protected boolean editable = false;
protected String htmlTd = "";
protected boolean nowrap = true;
protected void copy(CellBase copyFrom) {
this.column = copyFrom.column;
this.row = copyFrom.row;
this.value = copyFrom.value;
this.editable = copyFrom.editable;
this.htmlTd = copyFrom.htmlTd;
this.nowrap = copyFrom.nowrap;
}
public String getColumn() {
return column;
}
public Integer getRow() {
return row;
}
public String getValue() {
return value;
}
public boolean isEditable() {
return editable;
}
public String getHtmlTd() {
return htmlTd;
}
public boolean isNowrap() {
return nowrap;
}
}
public class Cell extends CellBase {
private Cell() {
}
/**
* Required for bean spring binding on the jsp
*
* @param value
*/
public void setValue(String value) {
this.value = value;
}
public static class Builder extends CellBase {
public Builder() {
}
public Builder(Cell initializeFromCell) {
copy(initializeFromCell);
}
public Cell build() {
// any pre-creation validation here
Cell result = new Cell();
result.copy(this);
return result;
}
public Cell.Builder column(String column) {
this.column = column;
return this;
}
public Cell.Builder row(Integer row) {
this.row = row;
return this;
}
public Cell.Builder value(String value) {
this.value = value;
return this;
}
public Cell.Builder editable(boolean editable) {
this.editable = editable;
return this;
}
public Cell.Builder htmlTd(String htmlTd) {
this.htmlTd = htmlTd;
return this;
}
public Cell.Builder nowrap(boolean nowrap) {
this.nowrap = nowrap;
return this;
}
}
}
// Example usage
// new Cell.Builder().value("123.4567").htmlTd("align='right'").build()
This pattern looks extremely useful. I do, however, see one potential problem: it couples the Widget's clients to the Widget's build dependencies. This is an issue if the build algorithm has complex dependencies--perhaps on a properties file, a heavyweight database, etc.
The Gang of Four Abstract Factory pattern solves that problem by having the client use the factory through an interface. However, that pattern does not address constructor parameter scaling like the Bloch builder does.
Is there a way to get the best of both worlds, i.e., a modification of the Bloch pattern that would decouple Widget clients from Widget build dependencies?
Thanks,
Ken
Thanks for this awesome post. I was looking for this kind of information. Please continue writing....
Regards:-offshore software development India
Interesting blog, i usally be aware all about all different kind of sofware. i am online all the time, and this action allow me to see a site costa rica homes for sale and i like it too much. beyond all doubt without my computer i never would have seen this site too.
Thanks for sharing this article on Software development. It was very nice.
Looking for more..................Please continue.
Nice post and very helpful for fresh programmer. Article describes the best tips for software development. Please continue writing....
Regards:-
Hey nice idea. Thanks a lot for sharing it with us. Keep the good work continue.
Hello,great post. Information are pretty exciting and saved me huge amount of time which I have spend on something else instead of searching posts like this. I am waiting for more.
oui tres bien merci
nice blog.
great work
This post is exactly what I am interested. keep up the good work. we need more good statements.
This is one of the great blog post. I like your writing style. I appreciate your efforts. Keep posting some more interesting blog posts.
I am so grateful to read this such a wonderful post. Thank you for discussing this great topic.
Useful information shared..I am very pleased to study this article..many thanks for giving us nice information.
Very knowledgeable reading. This is such a great resource that you are providing.
Every day I do try to look for the knowledge like that,
hey,this is one of the best posts that I’ve ever seen; you may include some more ideas in the same theme. I’m still waiting for some interesting thoughts from your side in your next post.
I just wanted to say thanks for this informative post. I would be grateful if you continue with the quality of what we are doing now with your blog.
alien perfume - eternity perfume
This blog post motivated me to start programming in Java. heads up for the OP.
I have no words to express how useful your blog was to me in completing my job work successful. Thanks a lot.
In this blog you may find very interesting post. Personally i like this blog
Many thanks for useful review! It was nice to read it. If your business software needs improvements, use software reengineering provided by outsource company of software development.
These Java pattern specially this Widget x = new Widget.Builder("1", 1.0). was i searching now i found here.
Thank you for taking the time to write this blog post. Much appreciated, very valuable information. I now have a clear idea on what this matter is all about. Thank you so much.
A lot of thanks for this great tips. Casino affiliates always look for best casino affiliate programs to increase their revenue income from best casinos or poker rooms.
Thanks for mentioning this great review. For those who is searching for new autos, check auto quotes from top auto insurance companies.
Its interesting. Turn your attention on cheap homeowners insurance to help you to save on home policy.
Hey, I had been searching on this topic for a long while but I was not able to find great resources like that. Now I feel very confidence by your tips about that, I think you have choosen a great way to write some info on this topic.
http://songznlyrics.blogspot.com
goodone
Christ! most of the comments are just ad's. Good article.
This is one of the special post for me.your blog quality is good.This is one of the suitable post.
I anticipation it was activity to be some boring old post, but it absolutely compensated for my time. because your articles are having the great resourceful information.
(Wow, what a lot of spam comments!)
I posted about this on Stack Overflow, but since this seems to be the go-to search result on Bloch's Builder pattern, I thought I should post here, too.
There are a couple of places where your version varies from Bloch's, and I think Bloch's version is superior.
First, you have Widget's fields set in Builder.build() rather than the Widget constructor, which means they can't be final. This makes it harder to enforce Widget's immutability.
Second, you validate the Builder fields before constructing the Widget, instead of validating the Widget fields after constructing it. This seems intuitive, and I used to do it myself. However, Bloch points out (EJ 2ed Item 39) that if you do this, another thread can come along and muck with the Builder fields after the validation and before the constructor call (even if you're smart and don't share the Builder among threads, if any of the values in it are mutable , they're at risk) so it's safer to validate afterwards.
I suppose every person must read it.
Nice content, I trust this is a nice blog. Wish to see fresh content next time. Thanks for sharing this post with us. Keep it up. kamagra jelly
My way of using Builder pattern in Java, you may like
Valuable information for all. And of course nice review about the application. It contains truly information. Your website is very useful. Thanks for sharing. Looking forward to more!
Is that to cater for different situations or because of an evolution in how you have tackled the problem?
home page
"Static" no not thread safe here. This is key to define "static" inner class - this class is no reference outside class. This is a poor choice of key words from this point, because it confusing people.
It is "thread safe, because it is not expected to you by different threads example construction unit -- just create small parts, and then forget it.
To adhere to the more stricter builder pattern, we have the constructor take the builder as an argument. This way you can have the required fields as final. The fields are then check in the constructor so avoiding the threading issues previously talked about.
I think this really is among the most significant information for me.
And I'm glad reading your post.home page
"I always like to read a quality content having accurate information regarding the subject and the same thing I found in this post. Nice work."
Brian Lara Cricket 2007 Download
Need For Speed Most Wanted Download
EA Cricket 2012 Download
We are real estate consultant in noida,we deal in property in noida Real Estate Noida,flats in noida,plots in Noida,property in noida,delhi Ncr,Noida real estate.
Happy to see your blog as it is just what I’ve looking for and excited to read all the posts. I am looking forward to another great article from you.
love to see such sort of innovative article. Thanks for doing all the hard work required to write and collect all the information for the blog.
Has casually discovered right now this forum and it was registered to participate in discussion of this question. Thank you for sharing. Excellent day, Nice to see your blog about this great subject. uggs for cheap Im surely going to bookmark you! Thank you for your information. Thanks for the beneficial data. Maintain up the nice function.
Fantastic Post! I thoroughly enjoyed your content …very effectively written about important matter. Thanks for this service that you have provided for us. Loads of excellent writing here.
Awesome to see your website about this great topic.Boot for inexpensive I am absolutely going to save you. Thanks for the valuable information. Sustain up the great operate.
It is threadsafe actually. The fact that you are invokingcheap baseball jerseys
Bottom line – just get blogging! It’s amazing how many lucrative jobs I’ve gotten via my blogs. Plus my blogs have been a great way to show cases my writing just as much as clips, samples, etc. You said about on what do ecopreneurs say their most effective marketing.
Blog is best from reader/customer/client point of view. Its a clear , fast and good approach to make everything simple. I found some info on Free Likes but still i need some reference.
Hi This is fantastic and is a legitimate good post . I think it will assist me a lot inside the related stuff and is significantly useful for me.Wonderfully written I appreciate & must say good job..
Post a Comment