当我编写一些API时,我尽量避免引入新的接口,这通常会让我想要使用guava接口“Function”。例如,而不是:
// a new interface
interface URILookup {
public URI lookup(Object o);
}
public class Some {
public Some(URILookup u){//...}
}
我将URILookup
替换为Function<Object,URI>
,并在Some
的构造函数中记录使用情况。
我觉得这可能导致后来的代码无法读取,因为我可以将所有内容都变成一个函数。你应用什么标准来找到这种“通用”接口与引入新类型之间的平衡?
答案 0 :(得分:4)
我正在使用一个非常简单的规则。
当你编写应该执行某些泛型操作的代码时(例如,Guava的Iterables.transform()
将一些函数应用于iterable的元素;它根本不关心这个函数应该做什么或应该做什么),你使用通用接口,如Function<F, T>
。
当您编写 的代码时,任何“函数”传递给它的代码都应该这样做(就像在您的示例中一样 - Some
类期望它的构造函数参数应该以某种方式获取URI从一个对象),为它创建一个独特的界面会更自然。
这可以更正式地重新制定。如果你需要使用泛型类型的具体实例化,即对于任意Function<F, T>
和F
T
不是Iterables.transform()
,那么你最好创建单独的接口,如您的URILookup
而不是Function<Object, URI>
。否则你应该坚持使用通用接口。
当然,在边界情况下也有例外,例如,当代码在精神上是通用的但在实现意义上不是通用的(例如Function<T, Integer>
之类的东西)或者当您需要与第三方API兼容时。那么你的决定将取决于案件的具体细节。