到目前为止,我花了一些时间从 Java 社区获取提示来解决这个问题。
当然,我是 Java 类型安全概念的追随者(感谢 plalx)。因此,我的解决方案可能与参数化类型有关。
而且我也像许多其他人一样欣赏设计模式的概念(感谢 tgdavies)。因此,对于每种类型的标准,我使用带有一种方法的构建器模式。我将接受为
实现汽车功能方法
- 使用 String 的普通旧文字
- 以及String的指定参数
即:
myCar.withFeatures("Seat Heating", "Metallic Color", "Trailer Hitch");
以及通过使用静态方法 sp(...) 以稍微复杂的方式指定(比方说)查询参数或某种字符串参数
myCar.withFeatures(sp("MyFavourit"));
当然也是两者的混合,引入另一种静态方法 sr(...) 来表示字符串:
myCar.withFeatures(sr("Seat Heating"), sp("LoveThatColor"), sr("Trailer Hitch"));
在我们想在方法签名中使用可变参数来指定这些表示的情况下,两者的混合很重要,在这种情况下是汽车特征。
可以看出,这几乎是我在上面发布这个问题时所说的用法。
我怎样才能做到这一点?
起初我设计了一个接口来实现我的不同字符串表示:
public interface ValueTypeRepresentation<T> {
public Class<T> getClazz();
public QueryParameter<T> getQueryParameter();
public RepresentationType getRepresentationType();
public T getValue();
}
方法是确定表示是字面量还是参数,并分别获取字面量的值。参数本身稍后使用其名称。
clazz 成员是为了简化 Java 通用类型推断的目的,因为我将使用参数化类型来实现不同的类型表示。正如我所说,String 只是演出的开始。
然后我设计了一个抽象类来派生不同原始对象的具体表示类:
abstract class AbstractValueTypeRepresentation<T> implements ValueTypeRepresentation<T> {
private Class<T> clazz;
private RepresentationType representationType = RepresentationType.VALUE;
private QueryParameter<T> queryParameter;
private T value;
public AbstractValueTypeRepresentation(Class<T> clazz, T value) {
this.clazz = clazz;
this.representationType = RepresentationType.VALUE;
this.value = value;
}
public AbstractValueTypeRepresentation(QueryParameter<T> qp) {
this.clazz = qp.getClazz();
this.representationType = RepresentationType.PARAM;
this.queryParameter = qp;
}
@Override
public Class<T> getClazz() {
return clazz;
}
@Override
public QueryParameter<T> getQueryParameter() {
return queryParameter;
}
@Override
public RepresentationType getRepresentationType() {
return representationType;
}
@Override
public T getValue() {
return value;
}
}
为了区分该类型的文字和该类型的查询参数,我引入了这个枚举:
public enum RepresentationType {
PARAM, VALUE;
}
然后我设计了第一个具体的表示,这里用于我的 StringRepresentation(派生自上面的抽象类):
public class StringRepresentation extends AbstractValueTypeRepresentation<String> {
public static StringRepresentation sr(String s) {
return new StringRepresentation(s);
}
public static StringRepresentation sp(String name) {
return new StringRepresentation(new QueryParameter<String>(String.class, name));
}
public StringRepresentation(String value) {
super(String.class, value);
}
public StringRepresentation(QueryParameter<String> queryParameter) {
super(queryParameter);
}
}
显然,这很容易扩展到 Integer、Float、LocalDate 等的表示。