Java 8:使用静态方法而不是静态util类的接口

当我需要一堆无状态实用程序方法时,Java 8中的最佳实践是什么。 拥有一个不会被任何人实现的接口,即public interface Signaturespublic interface Environments ,或者以旧方式做得更好 – 拥有私有构造函数的public final class Signaturespublic final class Environments 枚举?

接口的主要目的是提供该类型的操作(方法)的类型和词汇表。 它们是有用且灵活的,因为它们允许多个实现,实际上它们被设计为允许在类层次结构中不相关的实现。

问题是,

拥有一个不会被任何人实现的界面是正确的吗?

在我看来,这样可以减少对接口的影响。 人们不得不环顾API以确定没有实现此接口的类,并且没有此接口的生产者或使用者。 有人可能会感到困惑,并试图创建一个接口的实现,但当然他们不会走得太远。 虽然可以使用所有静态方法的“实用程序接口”,但这并不像旧的不可构造的最终类习惯用语那样清晰。 后者的优点是类可以强制执行不能创建任何实例。

如果你看一下新的Java 8 API,你会发现尽管能够在接口上添加静态方法,仍然会使用最终的类习惯用法。

接口上的静态方法已经用于诸如工厂方法之类的东西来创建那些接口的实例,或者用于在这些接口的所有实例中具有普遍适用性的实用方法。 例如,请参阅java.util.streamStreamCollector接口。 每个都有静态工厂: Stream.of()Stream.empty()Collector.of()

但另请注意,每个都有伴随实用程序类StreamSupportCollectors 。 这些是纯实用程序类,仅包含静态方法。 可以说它们可以合并到相应的接口中,但这会使接口混乱,并且会模糊类中包含的方法的关系。 例如, StreamSupport包含一系列相关的静态方法,这些方法都是SpliteratorStream之间的适配器。 将这些合并到Stream可能会让事情变得混乱。

我会用最后一堂课。 更好地告诉我它是一个带有一些实用方法的助手类。 接口定义是我期望实现的东西,以及帮助某人实现接口的方法。

在良好的面向对象设计中,没有很多(如果有的话)无状态实用方法。

我要处理的最好的技术是使用状态(对象)来处理函数。

所以不要这样做

  Temperature.farenheitFromCelcius(...); 

我做

  public class FarenheitFromCelcius implements Function { public Farenheit apply(Celcius celcius) { return new Farenheit(5 * celcius.getValue() / 9 + 32); } } 

这有一些优点。 一个是它可以更容易地从内存中卸载。 另一个是你可以节省类型识别接口的数量,你可以在方法之间传递实用程序方法,最后可以利用Java类型层次结构。

成本很低。 基本上你必须改变方法的应用方式。

  public  R convertTemp(T temp, Function conversion) { return conversion.apply(temp); } 

当然,你永远不会编写一个完整的方法来封装面向对象的函数,但我必须展示一个例子……

添加接口中的静态方法有两个主要目的:

  1. 在子类中实现不良的情况下,可以使用静态接口方法来提供检查(例如,如果值为null)。

  2. 避免使用通用实用程序类(如Collections )并通过适当的接口调用静态方法。

因此,如果您打算与相应的类共享function,那么这是一个非常好的做法。

更新:

如果您希望构建纯函数集合,那么您可能希望将抽象类与静态方法和私有构造函数一起使用。