【发布时间】:2013-09-08 01:34:07
【问题描述】:
情况:
我有一个看起来有点像这样的类层次结构。请注意,我的真的看起来不是这样的,我只是这样写它以使其更短,并且在我看来更清晰。
public abstract BaseClass {
private Alpha a;
private Beta b;
public Alpha getAlpha() { return a; }
public Beta getBeta() { return b; }
public BaseClass setAlpha(Alpha a) { this.a = a; return this; }
public BaseClass setBeta(Beta b) { this.b = b; return this; }
}
public Foo extends BaseClass {
@Override
public Foo setBeta(Beta b) {
super.setBeta(b);
doSomethingElse();
return this;
}
public Gamma getGamma() { return g; }
public Foo setGamma(Gamma g) { this.g = g; return this; }
}
public Bar extends BaseClass {
private Omega o;
@Override
public Bar setAlpha(Alpha a) {
super.setAlpha();
doSomethingElse();
return this;
}
public Omega getOmega() { return o; }
public Bar setOmega(Omega o) { this.o = o; return this; }
}
问题:
上面列出的这些方法还有很多。请注意,它们不符合相同的接口。使用Foo 和Bar 并且需要调用setGamma 和setOmega 的类始终可以访问最具体的类。但是,同样的类也需要调用setAlpha 和setBeta。但是,除非我重写它们,否则这些方法不会返回正确的类型。
选项:
- 重写
BaseClass的每个方法只是为了改变返回类型- 似乎有很多不必要的代码
- 在
BaseClass中声明每个方法,如setGamma和setOmega抽象。这可能会奏效,除非我必须为完全没有意义的类定义它。 - 类似于#2,除了我没有声明这些方法抽象,我给他们一个实现 -
throw new UnsupportedOperationException() - 与 #3 类似,但我只是忽略了这个问题,而不是抛出
Exception。 - 始终将我的所有构建器都放在最具体的返回类型之前。即
someBar.setOmega().setAlpha()但不是someBar.setAlpha().setOmega()
所有这些选项看起来都很恶心。有人有更好的吗?
注意:这种情况不太像这种情况:Java - Inherited Fluent method return type to return incident class' type, not parent's,因为它不是真正的泛型问题。
【问题讨论】:
-
如果您需要在
setBeta或setAlpha期间致电doSomethingElse(),您别无选择。 -
我认为您可以将
BaseClass泛化并让setAlpha/Beta返回<T>,但我今晚还没来得及提出签名。
标签: java design-patterns fluent return-type