제네릭에 대한 하루 하루 더 고투.Java 유창한 건축업자 및 상속
나는 다음과 같은 상속 트리 Control
객체로 설정 한 : 비 추상적 인 객체 각각에 대해
BaseControl
|_SimpleControl
|_MultipleControl
|_AutocompleteControl
|_SelectControl
을 내가 지금 이러한 개체를 쉽게 만들 수 있습니다 빌더를 제공하고자이 나무에. 여기에 지금까지 무엇을 가지고 :
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;
}
}
하지만 놀랍게도 예기치 않은 결과가 있습니다. 예를 들어
다음 코드에서 나는 사실에도 불구하고 세터를 호출 할 MultipleControl
에 control
캐스팅해야 그 또한 C extends MultipleControl
...
, 다음 build()
메서드 호출 : SimpleControl
대신 AutocompleteControl
의 new AutocompleteControlBuilder<AutocompleteControl, AutocompleteControlBuilder>("url", AutocompleteType.STANDARD).build());
반환하지 않습니다 의미, 내가 명시 적으로 형식 매개 변수를 제공합니다.
마지막 빨대는 내가 달성하려고하는 간결함과 명확한 코드가 추한 new AutocompleteControlBuilder<AutocompleteControl, AutocompleteControlBuilder>
생성자 호출에 의해 사망합니다. 아무도이 문제를 해결하는 모범 사례를 가르쳐 줄 수 있습니까?
나는'''builder''' 필드가있는 이유를 묻습니다. 나는 네가 그것을 사용하는 것을 보지 못한다. Java는 이미 covariant returns 유형을 가지고 있습니다. 언뜻보기에는 두 가지 유형 매개 변수를 모두 제거 할 수 있다고 말하고 싶습니다. 둘 다 구현 세부 사항 인 것처럼 보이기 때문입니다. 그것은 실제로 사용에 의존하지만 ... –
이 설치에 대한 빠른 질문이 있습니다. mr.nothing, 당신은 실제로 'SimpleControl'이 아닌 추상이 필요합니까? – EpicPandaForce
흠, JavaFX도 빌더와 함께 시작했으며 요즘에는 빌더가 없어도 마찬가지입니다. 따라서 건축업자들은 문체의 단점을 가지고 있습니다. 귀하의 경우 : 더 적은 생성자, 컨트롤 클래스 자체의 팩토리 메서드 ('RadioButton.create(). label ("not me").() :') –