Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
177 views
in Technique[技术] by (71.8m points)

java - Keeping builder in separate class (fluent interface)

Foo foo = Foo.builder()
    .setColor(red)
    .setName("Fred")
    .setSize(42)
    .build();

So I know there is the following "Builder" solution for creating named parameters when calling a method. Although, this only seems to work with inner static classes as the builder or am I wrong? I had a look at some tutorials for builder pattern but they seem really complex for what im trying to do. Is there any way to keep the Foo class and Builder class separate while having the benefit of named parameters like the code above?

Below a typical setup:

public class Foo {
    public static class Builder {
        public Foo build() {
            return new Foo(this);
        }

        public Builder setSize(int size) {
            this.size = size;
            return this;
        }

        public Builder setColor(Color color) {
            this.color = color;
            return this;
        }

        public Builder setName(String name) {
            this.name = name;
            return this;
        }

        // you can set defaults for these here
        private int size;
        private Color color;
        private String name;
    }

    public static Builder builder() {
        return new Builder();
    }

    private Foo(Builder builder) {
        size = builder.size;
        color = builder.color;
        name = builder.name;
    }

    private final int size;
    private final Color color;
    private final String name;
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can sure change the fields of your Builder class to be private - then you just need a (public) getter method for each "property" on the builder; and the constructor in Foo calls those methods; instead of just fetching the fields in the Builder object.

Then you can just move your Builder class out of Foo. Simple and straightforward.

But keep in mind: in the end, Builder and Foo are very closely related. They share a common set of fields by design. So any change to Foo affects Builder; and vice versa. Thus it makes a lot of sense to keep them "close together". Maybe not as inner/outer class, but maybe still within the same source file! But then ... only one of them can be public. Is that really what you want?!

In other words: don't rip things apart just "because you can". Only do it if you have good reasons to do so, and if the thing that comes out of that is better than your current solution!

Edit: your problem might not be separation of Foo and Builder, but the fact that your Foo class has too many fields in the first place. Dont forget about the single responsibility principle ... when your class needs more than 5, 6 fields ... it is probably doing too much and should be further sliced! Keep in mind: good OO design is first of all about behavior; not about having 10, 20 fields within some object!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...