You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@polygene.apache.org by Niclas Hedhman <ni...@hedhman.org> on 2017/06/12 01:39:50 UTC
Tip: Builder Pattern
I have for quite long been a little bit irritated over the Builders that
are required, especially since often I forget what is required and get a
runtime exception very late. Also, I tend to duplicate the builder
boilerplate all over the place.
Recently, I have tried to remember to do the following pattern...
Say we have a Value like;
public interface Address
{
Property<String> street();
Association<City> city();
Property<String> zipCode();
Association<Country> country();
}
And say for the sake of argument that the Country is an Entity, but City is
a Value.
I would then consider to create a explicit builder, inside the same
interface declaration;
class Builder
{
private final UnitOfWorkFactory uowf;
private final ValueBuilder<Address> addressBuilder;
private final ValueBuilder<City> cityBuilder;
private final Address addressPrototype;
private final City cityPrototype;
public Builder( @Structure ValueBuilderFactory vbf, @Structure
UnitOfWorkFactory uowf )
{
this.uowf = uowf;
addressBuilder = vbf.newValueBuilder( Address.class );
cityBuilder = vbf.newValueBuilder( City.class );
addressPrototype = addressBuilder.prototype();
cityPrototype = cityBuilder.prototype();
}
@UnitOfWorkPropagation( MANDATORY)
public Address create( String street, String cityName, String
zipCode, String countryCode ) {
cityPrototype.name().set( cityName );
City city = cityBuilder.newInstance();
Country country = uowf.currentUnitOfWork().get( Country.class,
StringIdentity.fromString( countryCode ) );
addressPrototype.street().set( street );
addressPrototype.city().set( city );
addressPrototype.zipCode().set( zipCode );
addressPrototype.country().set( country );
return addressBuilder.newInstance();
}
}
And this is an Object
so,elsewhere
@Structure
private ObjectFactory factory;
factory.newObject( Address.Builder.class ).create( "10, CH5A,
Canary Residence", "Cheras", "43200", "MY" );
And if I am really pressed for performance, then Address.Builder instance
can also be kept as a field, and a bunch of value builder initialization is
not happening on each instantiation.
Cheers
--
Niclas Hedhman, Software Developer
http://polygene.apache.org - New Energy for Java