Java BuilderTestPattern - how to avoid a template?

There are many value objects in my project.

I am using the lombok project to eliminate some pattern, so my value objects look like this:

@Value @Accessors(fluent = true) public class ValueObject { private final String firstProp; private final int secondProp; } 

Not bad, almost no templates.

And now, I use the all-args constructor quite often in my tests. It looks pretty dirty, so I thought that instead we would choose the Builder Pattern option:

 public class ValueObjectBuilder { private static final int DEFAULT_VALUE_FOR_SECOND_PROP = 666; private String firstProp = "default value for first prop; private int secondProp = DEFAULT_VALUE_FOR_SECOND_PROP; private ValueObjectBuilder() {} public static ValueObjectBuilder newValueObject() { return new ValueObjectBuilder(); } public ValueObjectBuilder withFirstProp(String firstProp) { this.firstProp = firstProp return this; } public ValueObjectBuilder withFirstProp(int secondProp) { this.secondProp = secondProp; return this; } public ValueObject build() { return new ValueObject( firstProp, secondProp ); } } 

and now the code looks pretty good:

 ValueObjectBuilder .newValueObject() .withFirstProp("prop") .withSecondProp(15) .build(); 

Now the problem is that, as I mentioned, I have to write a lot of similar classes ... I'm already tired of copying into them.

I am looking for, this is black magic - a smart tool that will somehow generate this code for me.

I know there is @Builder annotation in Lombok, but it does not meet my requirements. That's why:

1) I cannot provide default values โ€‹โ€‹in lombok Builder. Well, actually, itโ€™s possible - by implementing a builder class template, for example,

 @Builder public class Foo { private String prop; public static class FooBuilder() { private String prop = "def value"; ... } } 

which also generates some patterns.

2) I can not find a way to put a prefix on each field accessory in lombok builder. Maybe @Wither can help here? But I do not know how to use it correctly.

3) The most important reason: I do not create a โ€œnaturalโ€ builder. As far as I understand, lombok is designed to create a Builder for a given annotated class - I don't know if there is a way to return any other object from the build() method.

So to summarize: Do you know any tool that could help me? Or maybe all of the things that I mentioned can actually be achieved with the help of Lombok?

EDIT

Ok, so I probably found a solution for this particular case. With a Lombok we can use:

 @Setter @Accessors(chain = true, fluent = true) @NoArgsConstructor(staticName = "newValueObject") public class ValueObjectBuilder { private String firstProp = "default"; private int secondProp = 666; public ValueObject build() { return new ValueObject(firstProp, secondProp); } } 

Cheers, Slawek

+8
java builder lombok bytecode-manipulation boilerplate
source share
2 answers

I know this is old, but if anyone else comes across this, I have found an alternative solution to provide default values โ€‹โ€‹for the builder.

Override the construction method and specify default values โ€‹โ€‹before returning the builder. So, in the above case:

 @Builder public class Foo { private String prop; public static FooBuilder builder() { return new FooBuilder().prop("def value"); } } 

This is not an ideal solution, but is superior to overriding the entire builder or having your own constructor (which is painful IMHO if there are many variables. It would be nice to have something in the @With lines or the @Default annotation to handle this.

+5
source share

Try Bob-the-builder for eclipse. Hmm .. I think this works best if you use the ellipsis! If you are not using eclipse, there are several related projects mentioned at the bottom of the page, links to which may be useful.

+1
source share

All Articles