gpt4 book ai didi

Java 流利的构建器和继承

转载 作者:行者123 更新时间:2023-11-30 10:41:34 25 4
gpt4 key购买 nike

又一天又一次与泛型作斗争。

我有一组 Control具有以下继承树的对象:

BaseControl
|_SimpleControl
|_MultipleControl
|_AutocompleteControl
|_SelectControl

我想为这棵树中的每个非抽象对象提供构建器,以便可以轻松创建这些对象。这是我目前所拥有的:

基础控制构建器:

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();
}

简单控件生成器:

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;
}
}

多控件构建器:

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;
}
}

自动完成控件构建器:

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;
}
}

但令人惊讶的是,我得到了一些意想不到的结果。
例如,在下面的代码中我必须转换 controlMultipleControl尽管 C extends MultipleControl 仍然调用 setter ...

此外,以下build()方法调用:new AutocompleteControlBuilder<AutocompleteControl, AutocompleteControlBuilder>("url", AutocompleteType.STANDARD).build());返回 SimpleControl而不是 AutocompleteControl这没有意义,因为我明确提供了类型参数。

最后一根稻草是我试图实现的简洁明了的代码被丑陋扼杀了 new AutocompleteControlBuilder<AutocompleteControl, AutocompleteControlBuilder>构造函数调用。谁能指出解决此问题的最佳做法?

最佳答案

好的,为了正确设置它,您应该进行一些更改:

public class SimpleControlBuilder<C extends SimpleControl, B extends SimpleControlBuilder<C, B>>
extends BaseControlBuilder<SimpleControl, SimpleControlBuilder<C, B>> { // this should extend with the extension classes

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() { // this should return B
control.setDisabled(true);
return this;
}

@Override
protected SimpleControl createObj() { // this should return C
return new SimpleControl();
}

@Override
protected SimpleControlBuilder<C, B> getThis() { // this should return B
return this;
}
}

也就是说

public abstract class SimpleControlBuilder<C extends SimpleControl, B extends SimpleControlBuilder<C, B>>
extends BaseControlBuilder<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 B disabled() {
control.setDisabled(true);
return getThis();
}
}

abstract class MultipleControlBuilder<C extends MultipleControl, B extends MultipleControlBuilder<C, B>>
extends SimpleControlBuilder<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 B multiple() {
control.setMultiple(true);
return getThis();
}
}

public abstract class AutocompleteControlBuilder<C extends AutocompleteControl, B extends AutocompleteControlBuilder<C, B>>
extends MultipleControlBuilder<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);
control.setAutocompleteUrl(url);
control.setAutocompleteType(autocompleteType);
}

public AutocompleteControlBuilder(final Enum<?> en, final String url,
final AutocompleteType autocompleteType) {
this(en.name(), en.toString(), url, autocompleteType);
}
}

这在 MultipleControl extends SimpleControlAutocompleteControl extends MultipleControl 时有效,并且您有 SimpleControl 的具体扩展,可以通过 返回它们自己getThis() 带有具体化的参数。

public class SomeControlBuilder extends MultipleControlBuilder<SomeControl, SomeControlBuilder> {
public SomeControlBuilder(final InputType type) {
super(type);
}

public SomeControlBuilder(final String id, final String caption,
final InputType type) {
super(id, caption, type);
}

public SomeControlBuilder(final Enum<?> en, final InputType type) {
super(en, type);
}

@Override
protected SomeControlBuilder getThis() {
return this;
}

@Override
protected SomeControl createObj() {
return new SomeControl();
}
}

关于Java 流利的构建器和继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38455844/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com