具有非平凡子类树的 Java 构建器模式



我熟悉将构建器模式与泛型和子类一起使用,但我看不出如何使其与非平凡的子类树一起工作(即 C 扩展 B 扩展 A(。以下是我正在尝试执行的操作的简单示例:

class A {
private final int value;
protected A(ABuilder builder) {
this.value = builder.value;
}
public int getValue() { return value; }
public static class ABuilder<T extends ABuilder<T>> {
private int value;
public T withValue(int value) {
this.value = value;
return (T) this;
}
public A build() {
return new A(this);
}
}
}
class B extends A {
private final String name;
public static BBuilder builder() {
return new BBuilder();
}
protected B(BBuilder builder) {
super(builder);
this.name = builder.name;
}
public String getName() { return name; }
public static class BBuilder<U extends BBuilder<U>> extends ABuilder<BBuilder<U>> {
private String name;
public U withName(String name) {
this.name = name;
return (U) this;
}
public B build() {
return new B(this);
}
}
}

如果我声明没有泛型类型的 BBuilder,一切都很好:

public static class BBuilder extends ABuilder<BBuilder>

由于我希望 BBuilder 由 CBuilder 扩展,因此我尝试使用与 ABuilder 相同的奇怪重复模板模式。但是像这样,编译器将BBuilder.withValue((视为返回一个ABuilder,而不是我想要的BBuilder。这:

B b = builder.withValue(1)
.withName("X")
.build();

不编译。任何人都可以看到我在这里做错了什么,我一直在尝试不同的泛型模式,但无法让它工作。

感谢任何有任何建议的人。

似乎您的错误只是声明了正确的参数:

class A {
private final int value;
public static <T extends Builder<T>> T builderA() {
return (T)new Builder<>();
}
protected A(Builder<? extends Builder<?>> builder) {
value = builder.value;
}
public static class Builder<T extends Builder<T>> {
private int value;
public T withValue(int value) {
this.value = value;
return (T)this;
}
public A build() {
return new A(this);
}
}
}
class B extends A {
private final String name;
public static <T extends Builder<T>> T builderB() {
return (T)new Builder<>();
}
protected B(Builder<? extends Builder<?>> builder) {
super(builder);
name = builder.name;
}
public static class Builder<T extends Builder<T>> extends A.Builder<T> {
private String name;
public Builder<T> withName(String name) {
this.name = name;
return this;
}
public B build() {
return new B(this);
}
}
}

客户端代码:

A a = A.builder().withValue(1).build();
B b = B.builder().withValue(2).withName("xx").build();

你确定你需要泛型吗?这种层次结构似乎在没有泛型的情况下工作正常。

static class A {
protected final int value;
protected A(ABuilder builder) {
this.value = builder.value;
}
public int getValue() {
return value;
}
@Override
public String toString() {
return "A{" +
"value=" + value +
'}';
}
public static ABuilder builder() {
return new ABuilder();
}
public static class ABuilder {
protected int value;
public ABuilder withValue(int value) {
this.value = value;
return this;
}
public A build() {
return new A(this);
}
}
}
static class B extends A {
protected final String name;
protected B(BBuilder builder) {
super(builder);
this.name = builder.name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "B{" +
"value=" + value +
", name='" + name + ''' +
'}';
}
public static BBuilder builder() {
return new BBuilder();
}
public static class BBuilder extends ABuilder {
private String name;
public BBuilder withName(String name) {
this.name = name;
return this;
}
@Override
public BBuilder withValue(int value) {
this.value = value * 2;
return this;
}
public B build() {
return new B(this);
}
}
}
static class C extends B {
private final String otherName;
protected C(CBuilder builder) {
super(builder);
this.otherName = builder.otherName;
}
public String getName() {
return otherName;
}
@Override
public String toString() {
return "C{" +
"value=" + value +
", name='" + name + ''' +
", otherName='" + otherName + ''' +
'}';
}
public static CBuilder builder() {
return new CBuilder();
}
public static class CBuilder extends BBuilder {
private String otherName;
public CBuilder withName(String name) {
this.otherName = name;
return this;
}
public C build() {
return new C(this);
}
}
}
public void test() {
A a = A.builder().withValue(10).build();
B b = B.builder().withValue(10).withName("B").build();
C c = C.builder().withName("C").build();
System.out.println("a = "+a);
System.out.println("b = "+b);
System.out.println("c = "+c);
}

最新更新