使用guava Function接口与引入新类型

时间:2014-01-08 11:43:31

标签: java api function guava

当我编写一些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的构造函数中记录使用情况。

我觉得这可能导致后来的代码无法读取,因为我可以将所有内容都变成一个函数。你应用什么标准来找到这种“通用”接口与引入新类型之间的平衡?

1 个答案:

答案 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兼容时。那么你的决定将取决于案件的具体细节。

BTW,对于Java来说这是真的(在我看来),但对于像Scala这样内置函数类型的其他JVM语言来说并不是这样。如果语言本身支持函数,那么您应该接受这种支持。