简体   繁体   English

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

[英]Java 8: Interface with static methods instead of static util class

What is best practice in Java 8 when I need a bunch of stateless utility methods.当我需要一堆无状态实用程序方法时,Java 8 中的最佳实践是什么。 Is it right to have an interface that will not be implemented by anyone ie public interface Signatures and public interface Environments , or is it better to do it the old way - have public final class Signatures and public final class Environments with private constructors ||拥有一个不会被任何人实现的接口是否正确,即public interface Signaturespublic interface Environments ,还是以旧方式做更好 - 拥有具有私有构造函数的public final class Signaturespublic final class Environments || enums?枚举?

The main purpose of interfaces is to provide a type and a vocabulary of operations (methods) on that type.接口的主要目的是提供一个类型和该类型的操作(方法)词汇表。 They're useful and flexible because they allow multiple implementations, and indeed they are designed to allow implementations that are otherwise unrelated in the class hierarchy.它们有用且灵活,因为它们允许多个实现,并且实际上它们被设计为允许在类层次结构中不相关的实现。

The question asks,问题问,

Is it right to have an interface that will not be implemented by anyone...?拥有一个不会被任何人实现的接口是否正确......?

This seems to me to cut against the grain of interfaces.在我看来,这与界面的纹理相悖。 One would have to look around the API to determine that there are no classes that implement this interface, and that there are no producers or consumers of this interface.人们必须环顾 API 以确定没有实现此接口的类,并且没有此接口的生产者或消费者。 Somebody might be confused and try to create an implementation of the interface, but of course they wouldn't get very far.有人可能会感到困惑并尝试创建接口的实现,但当然他们不会走得很远。 While it's possible to have a "utility interface" with all static methods, this isn't as clear as the old unconstructible final class idiom.虽然可以有一个包含所有静态方法的“实用程序接口”,但这并不像旧的不可构造的最终类习语那样清楚。 The advantage of the latter is that the class can enforce that no instances can ever be created.后者的优点是该类可以强制永远不能创建任何实例。

If you look at the new Java 8 APIs, you'll see that the final class idiom is still used despite the ability to add static methods on interfaces.如果您查看新的 Java 8 API,您会发现尽管能够在接口上添加静态方法,但仍然使用最终的类习惯用法。

Static methods on interfaces have been used for things like factory methods to create instances of those interfaces, or for utility methods that have general applicability across all instances of those interfaces.接口上的静态方法已用于诸如创建这些接口实例的工厂方法之类的事情,或者用于在这些接口的所有实例上具有普遍适用性的实用程序方法。 For example, see the Stream and Collector interfaces in java.util.stream .例如,请参阅java.util.streamStreamCollector接口。 Each has static factories: Stream.of() , Stream.empty() , and Collector.of() .每个都有静态工厂: Stream.of()Stream.empty()Collector.of()

But also note that each has companion utility classes StreamSupport and Collectors .但还要注意,每个都有配套的实用程序类StreamSupportCollectors These are pure utility classes, containing only static methods.这些是纯实用程序类,仅包含静态方法。 Arguably they could be merged into the corresponding interfaces, but that would clutter the interfaces, and would blur the relationship of the methods contained in the classes.可以说它们可以合并到相应的接口中,但这会使接口混乱,并且会模糊类中包含的方法的关系。 For example, StreamSupport contains a family of related static methods that are all adapters between Spliterator and Stream .例如, StreamSupport包含一系列相关的静态方法,它们都是SpliteratorStream之间的适配器。 Merging these into Stream would probably make things confusing.将这些合并到Stream可能会使事情变得混乱。

I would use the final class.我会使用最后一堂课。 Communicates to me better that it is a helper class with some utility methods.更好地与我沟通,它是一个带有一些实用方法的帮助类。 An interface definition is something I would expect to be implemented and the methods to be there to assist someone implement the interface.接口定义是我希望实现的东西,以及用于帮助某人实现接口的方法。

In a good object oriented design, there are not many (if any) stateless utility methods.在一个好的面向对象设计中,没有很多(如果有的话)无状态实用程序方法。

The best technique I've come to deal with is to use state (Objects) to deal with the function.我遇到的最好的技术是使用状态(对象)来处理函数。

So instead of doing所以而不是做

 Temperature.farenheitFromCelcius(...);

I do我愿意

 public class FarenheitFromCelcius implements Function<Celcius, Farenheit> {

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

 }

This has a few advantages.这有几个优点。 One being that it can be unloaded from memory much more easily.一是它可以更容易地从内存中卸载。 Another being that you can save on the number of type identifying interfaces, you can pass utility methods between methods, and a final being that you can leverage the Java type hierarchy.另一个是您可以节省类型识别接口的数量,您可以在方法之间传递实用方法,最后一个是您可以利用 Java 类型层次结构。

The costs are minimal.成本是最低的。 Basically you have to alter how the method is applied.基本上你必须改变方法的应用方式。

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

Naturally you'd never write a full method to encapsulate an object oriented function, but I had to show an example...自然你永远不会写一个完整的方法来封装面向对象的函数,但我必须展示一个例子......

Static methods in interfaces were added with two primary purposes:添加接口中的静态方法有两个主要目的:

  1. In case of poor implementation in subclasses static interface methods can be used to provide checks (eg if a value is null).如果子类中的实现不佳,静态接口方法可用于提供检查(例如,值是否为空)。

  2. Avoid using general utility classes (like Collections ) and calling static methods through their proper interface.避免使用通用实用程序类(如Collections )并通过其适当的接口调用静态方法。

So, it is a very good practice if you intend to share functionality to the corresponding classes.因此,如果您打算将功能共享给相应的类,这是一个非常好的做法。

update:更新:

If you wish to build a pure collection of functions then you may want to use the abstract class with static methods and a private constructor.如果您希望构建一个纯函数集合,那么您可能需要使用带有静态方法和私有构造函数的抽象类。

in your case I would go for the final class instead of getting the fatigue that someone might implement or inherent this .在你的情况下,我会去参加最后一堂课,而不是因为有人可能实施或固有this而感到疲劳。 For use-cases where you want a static util interface.对于需要静态 util 接口的用例。 I guess we need a final interface for that...我想我们需要一个最终的接口......

public final class Util {

      private Util {
          throw new AssertionError("Please don't invoke me");
       }

    public static someUtilMethod() {}

    private static someHelperUtilMethod() {}

    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM