Reputation: 1706
I know there are several questions about the builder pattern.
- Use builder pattern from the constructor in a subclass
- When would you use the builder pattern
- Java improving builder pattern on a specific class
- Builder design pattern why do we need a director
So far I used the builder pattern like descripted in Bloch Item 2.
Yesterday I changed some small detail. I added a public constructor for the default values. So you could use both the Builder for a complex object or a constructor for simple object with the necessary values.
public class Blub {
private final String id;
public Blub( final String id ) {
this( Blub.Builder(id) );
}
private Blub( Builder builder ) {
this.id = builder.id;
}
public static class Builder {
private final String id;
public Builder( final String id ) {
this.id = id;
}
public Blub build() {
return new Blub(this);
}
}
}
But I am not sure if this has a design flaw. Because if I finalize the class I'm sure there are no disadvantages. So in the easy case, it would be possible to do call the Blub constructor.
new Blub("1a");
instead of
(new Blub.Builder("1a")).build();
But if I don't finalize the class it would be possible to extend it and do all kind of stuff in the new constructor. And I am not sure if there are no cases to mess this up now. Any idea?
Upvotes: 2
Views: 3055
Reputation: 3749
If you're going to use a Builder (or Factory pattern for that matter), it is usually counter-intuitive to have parameterized constructors as well (unless they are dependencies and you are using IoC). You are essentially breaking the orthogonality and DRY principle. Builder and Factory patterns are usually used to solve construction challenges where creating an instance is non-trivial or otherwise error prone.
In your case, this does not seem to be.
Is it a design flaw? No. Can it potentially cause the API to become confusing? Absolutely. Particularly over time, as more code divergers and starts using either method A and B. Are you going to explain to new developers when they should use method A for creating objects or when they should use method B?
Upvotes: 2
Reputation: 31648
One thing that I often do is provide a builder AND static factory methods to build the common simple cases. This way you can still have a private constructor and get intent revealing clean ways to construct the default cases.
Blub blub = Blub.createWithId("id");
This also lets you add several static factory methods without having to have multiple constructors or constructors with confusing parameters.
Upvotes: 1