5

我正在尝试创建一个构建器模式,该模式使用泛型来提供对某些方法的类型检查。目前我有以下工作:

ParameterBuilder.start(String.class).setName("foo").setDefaultValue("Hello").build();
ParameterBuilder.start(Integer.class).setName(bar).setDefaultValue(42).build();
ParameterBuilder.start(Boolean.class).setName(bar).setDefaultValue(false).build();

使用代码:

public class ParameterBuilder<T> {
  private String name;
  private T defaultValue;

  public static <T2> ParameterBuilder<T2> start(Class<T2> type) {
    return new ParameterBuilder<T2>();
  }
  // Other methods excluded for example
}

因此,该方法的输入类型setDefaultValue由传递给该方法的内容定义start,就像我想要的那样。

但现在我想扩展传入的内容start()以包含更多信息。本质上,我想为我创建的参数传递一个“类型”。有时这些参数会是“email”、“url”等。默认值仍然是已知类型(在这些情况下为字符串),所以我想要这样的东西:

ParameterBuilder.start(EMAIL).setName("email").setDefaultValue("foo@bar.com").build();
ParameterBuilder.start(URL).setName("website").setDefaultValue("http://www.somewhere.com").build();

目前 EMAIL 和 URL 是枚举,其中包含默认值的类。但是如果我沿着这条路线走,我将如何实例化参数构建器?

public static <T2> ParameterBuilder<T2> start(ParameterType paramType) {
  Class<T2> type = paramType.getTypeClass();
  // How do I instantiate my ParameterBuilder with the right type?
}

如果不能使用枚举来完成(我可以看到是这种情况),是否有人对不同的解决方案有建议?

4

3 回答 3

2

我认为每个类类型都需要一个枚举(我不明白如何让一个枚举涵盖多种类型并保持工作正常)。在这种情况下,一个通用的通用接口可以做你想做的事。然后,如果有帮助,您可以创建某种工厂来提供枚举常量。

这编译:

static interface ParameterType<T> {}

static enum ParameterTypeEnum implements ParameterType<String> { EMAIL; }

public static void main(String[] args) {
    ParameterBuilder
           .start(ParameterTypeEnum.EMAIL)
           .setName("email")
           .setDefaultValue("foo@bar.com")
           .build();
}

public static class ParameterBuilder<T> {

    private String name;
    private T defaultValue;

    public static <T2> ParameterBuilder<T2> start(ParameterType<T2> paramType) {
        return new ParameterBuilder<T2>();
    }

    ParameterBuilder<T> setName(String name) {
        this.name = name;
        return this;
    }

    ParameterBuilder<T> setDefaultValue(T defaultValue) {
        this.defaultValue = defaultValue;
        return this;
    }

    void build() {}
}
于 2013-08-07T10:56:09.380 回答
0

我不确定您要使用它的上下文,但我认为以下可能是一个选项。

您可以遵循 Open/Closed 原则并创建一个接口Parameter,并且每种类型都有一个实现。这样做的好处是,您不需要为所需的每个新参数添加新的枚举值。您可以稍后将类传递给ParameterBuilder而不是枚举,并且ParameterBuilderandParameter将一起构建您需要的内容。

因此ParameterBuilder.start()可以返回特定的实例,Parameter并且参数可能具有不同的方法,具体取决于参数的类型。

我不认为这个答案真的很好,但希望可以为您提供有关如何为您的上下文构建潜在解决方案的提示。

于 2013-08-07T10:48:53.410 回答
0

您可以为这些电子邮件和网址类型创建对象层次结构

public class DefaultType {
    protected String name;
    protected String defaultValue;
    //some constructor
}

public class EmailType extends DefaultType {
    ...
}

public class URLType extends DefaultType {
    ...
}

那么参数生成器可能看起来像这样:

public static ParameterBuilder start(DefaultType type) {
    ParameterBuilder builder = new ParameterBuilder(type);
    builder.setType(type);
    return builder;
}

然后你可以这样称呼它:

ParameterBuilder.start(new EmailType("name","value");...

这有帮助还是您不想朝这个方向发展?

于 2013-08-07T10:50:10.983 回答