在构建器中声明父类的实例,并使用该变量初始化每个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对象中的成员,并且由于不必从中复制值,因此可能会提高性能。生成器到最终对象。