The @Builder doesnt provide a protected Builder class by default for encapsulating any build time constraint handling

212 views
Skip to first unread message

VMurthy

unread,
Dec 24, 2013, 12:19:58 AM12/24/13
to project...@googlegroups.com
Hi All

I have a small issue with the @Builder which i would like to understand if there are otherways to do this.
Currently @Builder provides a public class <ClassName>Builder. However it exposes the Default Builder class to Public too early in my opinion. Rather they could provide a level to be specified

For eg in the below class: If i dont want to provide a dfault value for runningSum and dont want a public setter; i cannot do that as the public class HasPathSumVisitorBuilder is already wide open to public and clients will use that.
If instead ; an option to set the default Builder (level=AccessLevel.PROTECTED) is given; then my own extension Builder class will be the sole point of contact and that way i can add constraints handling without exposing the default builder.

I know we could completely write the Builder class by ourselves; however the point i am noting here is; the default builder takes care of 80% of mundane code; its just that this little bit done during build() time is what i would like to add with a nice encapsulation.

Should this be raised as a feature.

thanks
Murthy
@Log4j2
@Data(staticConstructor = "of")
@Accessors(fluent = true)
@EqualsAndHashCode(callSuper = false)
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
@Builder
public class HasPathSumVisitor implements Visitor<Integer> {
    static final Logger log = LogManager
            .getLogger(StringFormatterMessageFactory.INSTANCE);
   
    Integer targetSum;
    @Getter AtomicInteger runningSum;

    @Data(staticConstructor = "builder")
    public static class Builder extends HasPathSumVisitorBuilder {
        @Override public HasPathSumVisitor build() {
            Assert.notNull(super.targetSum,
                    "Please make sure to set the targetSum");
            //Just set runningSum to default if its null.
            if(super.runningSum==null)super.runningSum= new AtomicInteger(super.targetSum);
            Assert.state(super.runningSum.get() == super.targetSum,
                    " Running Sum cannot be different than targetSum");
            return super.build();
        }
    }
.....
}

Reinier Zwitserloot

unread,
Jan 8, 2014, 7:23:17 PM1/8/14
to project...@googlegroups.com
Lombok doesn't generate what is already there. So, just write something like:

@Builder
public class Foo {
    private class FooBuilder {}
    private FooBuilder build() { return new FooBuilder(); }
}

this means lombok will fill your FooBuilder class (with, note, public methods, and private fields!), and it won't generate the build() method as it's already there.
Reply all
Reply to author
Forward
0 new messages