又一天又一次與泛型相沖突。在此樹是我想提供生成器,這些對象可以輕鬆創建Java流利的構建器和繼承
BaseControl
|_SimpleControl
|_MultipleControl
|_AutocompleteControl
|_SelectControl
對於每個非抽象的對象:
我已經設置Control
對象具有以下繼承樹。以下是我迄今爲止:
BaseControlBuilder:
public abstract class BaseControlBuilder<C extends BaseControl, B extends BaseControlBuilder<C, B>> {
protected C control;
private B builder;
BaseControlBuilder() {
control = createObj();
builder = getThis();
}
public C build() { return control; }
protected abstract C createObj();
protected abstract B getThis();
}
SimpleControlBuilder:
public class SimpleControlBuilder<C extends SimpleControl, B extends SimpleControlBuilder<C, B>>
extends BaseControlBuilder<SimpleControl, SimpleControlBuilder<C, B>> {
public SimpleControlBuilder(final String id, final String caption,
final InputType controlType) {
super();
control.setId(id);
control.setCaption(caption);
control.setType(controlType);
}
public SimpleControlBuilder(final InputType controlType) {
this("", "", controlType);
}
public SimpleControlBuilder(final Enum<?> en, final InputType controlType) {
this(en.name(), en.toString(), controlType);
}
public SimpleControlBuilder<C, B> disabled() {
control.setDisabled(true);
return this;
}
@Override
protected SimpleControl createObj() {
return new SimpleControl();
}
@Override
protected SimpleControlBuilder<C, B> getThis() {
return this;
}
}
MultipleControlBuilder:
abstract class MultipleControlBuilder<C extends MultipleControl, B extends MultipleControlBuilder<C, B>>
extends SimpleControlBuilder<MultipleControl, MultipleControlBuilder<C, B>> {
MultipleControlBuilder(final InputType type) {
super(type);
}
MultipleControlBuilder(final String id, final String caption,
final InputType type) {
super(id, caption, type);
}
MultipleControlBuilder(final Enum<?> en, final InputType type) {
super(en, type);
}
public MultipleControlBuilder<C, B> multiple() {
((MultipleControl) control).setMultiple(true);
return this;
}
}
AutocompleteControlBuilder:
public class AutocompleteControlBuilder<C extends AutocompleteControl, B extends AutocompleteControlBuilder<C, B>>
extends MultipleControlBuilder<AutocompleteControl, AutocompleteControlBuilder<C, B>> {
public AutocompleteControlBuilder(final String url,
final AutocompleteType autocompleteType) {
this("", "", url, autocompleteType);
}
public AutocompleteControlBuilder(final String id,
final String caption, final String url,
final AutocompleteType autocompleteType) {
super(id, caption, InputType.AUTOCOMPLETE);
((AutocompleteControl) control).setAutocompleteUrl(url);
((AutocompleteControl) control).setAutocompleteType(autocompleteType);
}
public AutocompleteControlBuilder(final Enum<?> en, final String url,
final AutocompleteType autocompleteType) {
this(en.name(), en.toString(), url, autocompleteType);
}
@Override
protected AutocompleteControl createObj() {
return new AutocompleteControl();
}
@Override
protected AutocompleteControlBuilder<C, B> getThis() {
return this;
}
}
但令人驚訝的是,我得到了一些意想不到的結果。
例如,在下面的代碼我要投control
到MultipleControl
調用二傳手儘管C extends MultipleControl
...
此外,以下build()
方法調用:new AutocompleteControlBuilder<AutocompleteControl, AutocompleteControlBuilder>("url", AutocompleteType.STANDARD).build());
回報SimpleControl
代替AutocompleteControl
不使感覺,因爲我明確提供了類型參數。
而最後一根稻草是我試圖實現的簡潔明瞭的代碼被醜陋的new AutocompleteControlBuilder<AutocompleteControl, AutocompleteControlBuilder>
構造函數調用所殺死。有人能指出我解決這個問題的最佳做法嗎?
請問爲什麼你有''builder'''字段?我沒有看到你使用它。 Java已經有協變返回類型,乍一看,我可以說你可以刪除兩個類型參數,因爲它們都是實現細節。這真的取決於用途,雖然... –
我有一個關於這個設置的快速問題@ mr.nothing,你真的需要'SimpleControl'是非抽象的嗎? – EpicPandaForce
嗯,JavaFX也是以構建者開始的,現在沒有它們。所以建設者_can_有風格的缺點。在你的情況下:更少的構造函數,控制類本身的工廠方法('RadioButton.create()。label(「not me」))。build():') –