【发布时间】:2018-02-06 02:45:26
【问题描述】:
我想用静态内部类实现一个构建器模式,比如类 A 带有字段 (a1, a2, a3),B 带有字段 (b1, b2) 和 C 带有字段 (c1),而所有共享字段 ( s1, s2) 来自超类 SuperClass:
public class A extends SuperClass {
private final String a1;
...
private A(ABuilder builder) {
super(builder);
this.a1 = builder.a1;
...
}
public static class ABuilder extends SuperClassBuilder implements ABuilderInterface {
private String a1;
...
@Override
public ABuilder withA1(String a1) {
this.a1 = a1;
return this;
}
...
@Override
public SuperClass build() {
return new A(this);
}
}
}
因此,对于 B 和 C,构建器的不同之处在于它们拥有自己的字段并实现自己的接口(BBuilderInterface 和 CBuilderInterface),而这些接口仅定义要实现的方法:
public interface ABuilderInterface extends SuperClassBuilderInterface {
ABuilderInterface withA1(String a1);
...
}
...<interfaces for B and C>
public interface SuperClassBuilderInterface {
SuperClassBuilderInterface withS1(String s1);
...
SuperClass build();
}
// Usage of the builders:
public SuperClass foo() {
return new A.ABuilder()
.withA1(...) // returns ABuilderInterface
...
.withS1(...) // returns SuperClassBuilderInterface
...
.build();
}
public abstract class SuperClass {
private final String s1;
...
protected SuperClass(SuperClassBuilder builder) {
this.s1 = builder.s1;
...
}
protected static abstract class SuperClassBuilder implements SuperClassBuilderInterface {
private String s1;
...
@Override
public SuperClassBuilder withS1(String s1) {
this.s1 = s1;
return this;
}
...
@Override
public abstract SuperClass build();
}
}
现在你可以发现我在使用builder时必须注意先调用与子类相关的with...方法,然后将它们链接到超类的限制,这不是什么大问题一个交易,但仍不确定是否是好的做法。 另一方面,我可以将子类的 with... 方法一起添加到超类接口中,然后限制就消失了,但是我有一个混合了不同子类的 with... 方法的接口。
你更喜欢/建议哪一个?
【问题讨论】:
-
withS1()在ABuilder中返回什么? -
@alayor 在 ABuilder 中没有 withS1() 因为它使用的是父级。这个想法是 A、B、C 构建器仅包含其特定的 with... 方法,而共享的方法保留在超级构建器中
-
这是一个很常见的问题。一种模式是在超类上定义一个通用的“自我类型”,并通过其方法返回。
-
不清楚你的意思@shmosel
标签: java inheritance design-patterns builder