Java 使用Void作为可选参数的更好选择
我有一个接口指定方法,该方法将泛型类型作为用于创建URL的输入Java 使用Void作为可选参数的更好选择,java,oop,generics,Java,Oop,Generics,我有一个接口指定方法,该方法将泛型类型作为用于创建URL的输入 interface UrlGenerator<T> { String prepareUrl( T input ); } 现在我必须以另一种方式(在构造函数中)将所需的输入传递给实现类。这样我就失去了类的无状态特性,每次我想要更改输入时,我都必须用不同的构造函数参数重新创建它 class SchedulePageUrlGenerator implements UrlGenerator { publi
interface UrlGenerator<T> {
String prepareUrl( T input );
}
现在我必须以另一种方式(在构造函数中)将所需的输入传递给实现类。这样我就失去了类的无状态特性,每次我想要更改输入时,我都必须用不同的构造函数参数重新创建它
class SchedulePageUrlGenerator implements UrlGenerator {
public static final String QUERY_STRING_BASE = "?from=";
private final String showingBaseUrl;
private final LocalDate date;
public SchedulePageUrlGenerator( String showingBaseUrl, LocalDate date ) {
this.showingBaseUrl = showingBaseUrl;
this.date = date;
}
@Override
public String prepareUrl() {
DateTimeFormatter fmt = DateTimeFormat.forPattern( "yyyy-MM-dd" );
String dateStr = fmt.print( date );
return showingBaseUrl + QUERY_STRING_BASE + dateStr;
}
}
我认为我的设计肯定有一些根本性的问题。您似乎希望为不同的实现计算不同数量的参数 最接近这一点的方法是使用varargs
interface UrlGenerator<T> {
String prepareUrl(T... input );
}
// can use
System.out.println(new StaticUrlGenerator("url").prepareUrl());
//or
System.out.println(new StaticUrlGenerator("url").prepareUrl(null));
接口生成器{
字符串准备(T…输入);
}
//可以使用
System.out.println(新的StaticUrlGenerator(“url”).prepareUrl());
//或
System.out.println(新的StaticUrlGenerator(“url”).prepareUrl(null));
问题是SchedulePageUrlGenerator
是否真的是UrlGenerator
。如果它有不同的论点,那么我会说它不是。如果您的接口有可选参数,那么我想在调用代码中您必须执行以下操作:
// this is not a good pattern
if (urlGenerator instanceof SchedulePageUrlGenerator) {
(SchedulePageUrlGenerator)urlGenerator.prepareUrl();
} else {
urlGenerator.prepareUrl(...);
}
这似乎是一个黑客
综上所述,如果您的接口有更多的方法,并且只有prepareUrl(…)
不同,那么我认为将null
作为Void
参数传递到prepareUrl(…)
没有问题。我想我需要更多地了解调用框架,以了解如何生成参数,以及为什么null
参数会出现这样的问题
如果您的接口中有更多方法,另一种选择是同时使用带参数和不带参数的prepare方法:
String prepareUrl( T input );
String prepareUrlNoInput();
然后,根据哪个实现支持哪个,您可以抛出UnsupportedOperationException
。但是同样,如果您必须执行上面的instanceof
if
语句,那么我认为null
参数更好
我想我的设计一定有根本性的问题
唯一的错误是您试图将单参数方法和零参数方法混为一谈。你就是不能用Java来做。。。没有打开其他问题的大门
基本上你有三个选择:
- 坚持当前方法,在Void情况下显式传递
null
- 向接口添加第二个(无参数)方法来处理Void情况,并使其使用
调用单参数方法。当null
不是T
时,您的代码需要处理Void
,但它还是处理了null
- 重构接口,以便有两个不同的接口,一个使用
,另一个使用String prepareUrl()
,并将前者作为一个特例类实现String prepareUrl(T)
T
类型的整个空间内进行多态方法调用
(Varargs是个坏主意,因为这为多个参数打开了大门,而这些参数对您的问题可能毫无意义。)您可以从一开始就使用Varargs签名:
String prepareUrl(T…input)代码>在我看来就像一个Twitter API客户端:-)无论如何。。。在OO中,操作不是由名称定义的,而是由它们的行为定义的。在您的场景中,prepareUrl在不同的类中执行不同的操作。解决方案是为这两个方法指定不同的名称,以区分它们的操作。
// this is not a good pattern
if (urlGenerator instanceof SchedulePageUrlGenerator) {
(SchedulePageUrlGenerator)urlGenerator.prepareUrl();
} else {
urlGenerator.prepareUrl(...);
}
String prepareUrl( T input );
String prepareUrlNoInput();