D
Daniel Pitts
I was just thinking about the Builder pattern (because of Roedy's recent
post).
It seems to me that Builders are a special type of Factory, and in
general Factories /tend/ to prevent the client from specifying the
actual implementation to use. I was thinking about ways to give the
client some control, while allowing the builder to do its job as-well.
I was thinking of a double-indirection factory (bad name maybe?)
class Foo { public Foo(int bar, Baz baz) {} }
interface FooFactory {
Foo createFoo(int bar, Baz baz);
}
class FooBuilder {
private final FooFactory factory;
public FooBuilder(FooFactory factory) {this.factory = factory;}
public FooBuilder() {this.factory = new DefaultFooFactory();}
// builder methods etc...
public Foo toFoo() { return factory.createFoo(getBar(), getBaz()); }
}
This gives the client the ability to create a subclass foo builder, and
utilize the foo builder:
class SpecialFoo extends Foo {
SpecialFoo(int bar, Baz baz, Zip zip) {
super(bar, baz);
}
}
class SpecialFooBuilder implements FooFactory {
// builder methods to get "zip"
Foo createFoo(int bar, Baz baz) {
return new SpecialFoo(bar, baz, zip);
}
}
class Client {
public void stuff() {
SpecialFooBuilder specialFooBuilder = new SpecialFooBuilder();
FooBuilder fooBuilder = new FooBuilder(specialFooBuilder);
configureSpecialFooBuilder(specialFooBuilder);
configureFooBuilder(fooBuilder);
fooBuilder.toFoo().doFooThing();
}
}
This seems like it *might* be an anti-pattern, but I'm not sure. Have
any of you had to implement this design? How did it work out? I don't
actually have any real code for this, since I'm just thinking "out loud"
at the moment.
post).
It seems to me that Builders are a special type of Factory, and in
general Factories /tend/ to prevent the client from specifying the
actual implementation to use. I was thinking about ways to give the
client some control, while allowing the builder to do its job as-well.
I was thinking of a double-indirection factory (bad name maybe?)
class Foo { public Foo(int bar, Baz baz) {} }
interface FooFactory {
Foo createFoo(int bar, Baz baz);
}
class FooBuilder {
private final FooFactory factory;
public FooBuilder(FooFactory factory) {this.factory = factory;}
public FooBuilder() {this.factory = new DefaultFooFactory();}
// builder methods etc...
public Foo toFoo() { return factory.createFoo(getBar(), getBaz()); }
}
This gives the client the ability to create a subclass foo builder, and
utilize the foo builder:
class SpecialFoo extends Foo {
SpecialFoo(int bar, Baz baz, Zip zip) {
super(bar, baz);
}
}
class SpecialFooBuilder implements FooFactory {
// builder methods to get "zip"
Foo createFoo(int bar, Baz baz) {
return new SpecialFoo(bar, baz, zip);
}
}
class Client {
public void stuff() {
SpecialFooBuilder specialFooBuilder = new SpecialFooBuilder();
FooBuilder fooBuilder = new FooBuilder(specialFooBuilder);
configureSpecialFooBuilder(specialFooBuilder);
configureFooBuilder(fooBuilder);
fooBuilder.toFoo().doFooThing();
}
}
This seems like it *might* be an anti-pattern, but I'm not sure. Have
any of you had to implement this design? How did it work out? I don't
actually have any real code for this, since I'm just thinking "out loud"
at the moment.