在构建器中声明父类的实例,并使用该变量初始化每个Field,然后在构建器中分别分别声明每个变量,然后将构建器声明为构造器的一部分来初始化每个Field之间,有什么区别吗?

public class Foo {

    public int i;
    public String s;

    private Foo(Builder builder) {
        i = builder.i;
        s = builder.s;
    }

    public static class Builder {

        private int i;
        private String s;

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

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

        public Foo build() {
            return new Foo(this);
        }
    }

}




public class Foo {

    public int i;
    public String s;

    public static class Builder {

        private final Foo mFoo = new Foo();

        public Builder i(int i) {
            mFoo.i = i;
            return this;
        }

        public Builder s(String s) {
            mFoo.s = s;
            return this;
        }

        public Foo build() {
            return mFoo;
        }
    }

}

最佳答案

第一种方法是规范方法。

如我所见,第二种方法的主要局限性是:


您不能使Foo(正在构造的对象)的成员final,因为它们是在构造之后分配的。
您必须在正在构建的类中声明构建器,以便它可以访问私有成员或设置器,或者声明非私有成员或setter方法,以便构建器可以访问它们,即使该访问级别可能建后不宜。
正在构造的对象Foo处于几种不同的状态,这些状态可能无效。根据您使用哪种方法以这种增量方式构造对象,可能会限制您进行的验证。常用的构建器模式收集要构建的对象的所有状态,然后进行构建,从而使构造函数可以对最终状态进行所有必要的验证。
构建器不能构建多个对象。在通常的构建器模式中,您可以多次调用build()来构建多个对象,可能与对构建器方法的调用交错以修改后续对象。


对于第二种方法,我唯一能看到的真正好处是,您可以节省一些样板-不必重新声明builder对象中的成员,并且由于不必从中复制值,因此可能会提高性能。生成器到最终对象。

07-24 18:58
查看更多