We were unable to load Disqus. If you are a moderator please see our troubleshooting guide.

Sheridan • 14 years ago

What you are really replacing here is the Setter pattern, not the Builder pattern.  The big difference is that with a builder I can have private variables within the object that are initialized via the builder, but then are immutable.  There is no set property and no chance of having the value changed down the road.  This can allow me the avoid situations where the object might be in an inconsistent state.

Rodrigo Jordao • 14 years ago

I think you could still use the object initializer syntax for the builder. Just have the builder constructor do the value defaulting. Couple this with an implicit conversion operator and you get:

Foo foo = new FooBuilder { Bar = "bar" };

Nitin • 15 years ago

One more advantage is, it allows user to plugin their own custom implementation into framework. Please refer the following blog.

http://xeon2k.wordpress.com

Philip Schwarz • 16 years ago

The second item in 'Effective Java (2nd edition)' is 'Consider a builder when faced with many constructor parameters'.

And this advice is aimed at all code, not just test code. One of the points Joshua Bloch makes is that rather than using the following

NutritionFacts cocaCola = new NutritionFacts(240,8,100,0,35,27)

which is hard to write, and harder still to read, we can us the builder pattern

NutritionFacts cocaCola = NutritionFacts.Builder(240,8).calories(100).sodium(35).carbohydrate(27).build()

which simulates named optional parameters (required parameters, e.g. 240 and 8, are passed in to the Builder's constructor).

The Builder is an inner class, so it is easy to locate.

Mark Needham • 17 years ago

@joe I thought the implicit operator needs to go on the target class although just trying out what you suggested does seem to work which is really cool!

I'm sure I tried that a few times before I posted and couldn't get it to work but it certainly seems to work now - thanks for the tip

joe • 17 years ago

oops C&P error:

return new Foo {Bar = current.bar, Baz = current.baz, Bling = current.bling};

joe • 17 years ago

Why can't you apply the implicit operator to the builder class so that you end up with

public static implicit operator Foo(FooBuilder current)
{
return new Foo {Bar = bar, Baz = baz, Bling = bling};

}

Foo newFoo = new FooBuilder().Bar("A").Baz("B")

How does require a change to a non-test class?

Ville Oikarinen • 17 years ago

A fluent interface has also technical uses, besides pleasing the eye:

http://web.sysart.fi/develo...

In short: passing a fluent "sentence" around allows effective streaming of events, and the resulting code is beautiful.

Here is a more complex example, a converter from a parsed Java AST to an ngrease element (tree). The fluent building sentence is IMHO piped nicely in and out from the AST visitor methods with absolutely no need for any state management:

http://ngrease.svn.sourcefo...

Willie • 17 years ago

I don't quite understand why you'd do this and not just get rid of the automatic get;set and just return a default instead.

Like:

private foo = "defaultFoo";
public string Foo {get { return foo; } set { foo = value; } }

This way you could use the object initializer and have the same build pattern you're talking about.

Rob Hunter • 17 years ago

Building objects like this is a lot more transparent in languages that support keyword parameters:

#python
foo = Foo(bar="bar")

#ruby
foo = Foo.new(:bar => "bar")

It's very nice specify just what you care care about, and tell the reader what it is that you're specifying.

In my last couple of projects, I've enjoyed the use of the Machinist framework for building domain objects for integration tests.

You give Machinst blueprints for your objects (using a convenient internal DSL), and Machinist builds an object graph whenever you want one, allowing you to override just the parts you are interested in.