【发布时间】:2016-01-17 15:11:31
【问题描述】:
假设我有两个对象,都是通过构建器模式创建的,一个嵌套在另一个对象中:
class Parent {
private final Child child;
private Parent(Child child) {
this.child = child;
}
public static class Builder {
private Child child;
public Builder() {}
public Builder child(Child child) {
this.child = child;
return this;
}
public Parent build() {
return new Parent(child);
}
}
}
class Child {
private final long id;
private Child(Builder builder) {
this.id = builder.id;
}
public static class Builder {
private long id;
public Builder() {}
public Builder id(long id) {
this.id = id;
return this;
}
public Parent build() {
return new Child(this);
}
}
}
所以,显而易见的用法很简单:
Person.Builder parentBuilder = new Person.Builder().child(new Child.Builder().id(10).build());
制作很常见吗
public static class Builder {
private ChildBuilder child;
public Builder() {}
public Builder child(ChildBuilder child) {
this.child = child;
return this;
}
public Builder resetChildId() {
child.id(0);
return this;
}
public Parent build() {
Child childToPass = child.build();
return new Parent(childToPass);
}
}
这样以后仍然可以更新 child#id,但是由于后期绑定,最近在 Parent.Builder#build() 方法期间会抛出错误。
【问题讨论】:
-
dp Builder 允许您构建一个不可变对象,您无需修改,因此类成员上的 final 修饰符。因此,一旦创建了对象,就无法进行任何修改。另外,您需要更正 public Builder id(long id) { this.id = id; return this;} 和 public Builder child(Child child) { this.child = child;返回这个;}
-
很常见我不知道,我可以告诉你的是,在 Parent Builder 中,child() 方法接受一个 Child 对象,子对象是不可变的,你以后不能resetChildId,你需要为了保留 Child 构建器,这样您就可以稍后设置 id 并仅在您确定状态不再更改时构建。
-
@VadimKirilchuk 为什么不简单地传递子实例而不是构建器。如果你想改变孩子的一些东西,你可以替换整个孩子实例。如果您只想更改孩子的单件,则可以执行
parent.child(new ChildBuilder(parent.child()).setSomeProperty(...).build())之类的操作 -
@VadimKirilchuk 这就是我要说的,允许从现有的孩子构建构建器。因此,如果您想更改子属性,您可以通过从现有子构造
ChildBuilder来替换整个子实例。ParentBuilder将持有Child实例而不是ChildBuilder实例。 -
@VadimKirilchuk By the way, I wouldn't care about nice and clean error reporting to the UI. That's a UX problem which can be solved in the UI. 此外,如果您正确使用值对象,您可能根本不需要所有这些构建器。例如,您可能有一个强制执行 255 个字符规则的
ParentName类。然后,您的Parent对象可以期待ParentName而不是简单的字符串。
标签: java design-patterns builder