何时在 Java 中使用单方法接口

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15200362/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 18:49:33  来源:igfitidea点击:

When to use Single method Interfaces in Java

javaoopdesign-patternsinterface

提问by Narendra Pathai

I have seen in many libraries like Springwhich use a lot of interfaces with single methodsin them like BeanNameAware, etc.

我在许多库中都看到过,Spring它们使用了很多接口,其中包含单个方法,例如BeanNameAware,等等。

And the implementer class will implement many interfaces with single methods.

而实现者类将使用单一方法实现许多接口。

In what scenarios does it make sense to keep single method interfaces? Is it done to avoid making one single interface bulky for example ResultSet? Or is there some design standard which advocates the use of these type of interfaces?

在什么情况下保持单一方法接口有意义?例如,这样做是为了避免使单个界面变得笨重ResultSet吗?或者是否有一些设计标准提倡使用这些类型的接口?

采纳答案by gexicide

With Java 8, keeping the single method interface is quite useful, since single method interfaces will allow the usage of closures and "function pointers". So, whenever your code is written against a single method interface, the client code may hand in a closure or a method (which must have a compatible signature to the method declared in the single method interface) instead of having to create an anonymous class. In contrast, if you make one interface with more than one method, the client code will not have that possibility. It must always use a class that implements all methods of the interface.

在 Java 8 中,保持单一方法接口非常有用,因为单一方法接口将允许使用闭包和“函数指针”。因此,每当您的代码针对单个方法接口编写时,客户端代码可能会提交一个闭包或一个方法(必须具有与在单个方法接口中声明的方法兼容的签名),而不必创建匿名类。相比之下,如果你用多个方法制作一个接口,客户端代码就没有这种可能性。它必须始终使用一个实现接口所有方法的类。

So as a common guideline, one can say: If a class that only exposes a single method to the client code might be useful to some client, then using a single method interface for that method is a good idea. A counter example to this is the Iteratorinterface: Here, it would not be useful having only a next()method without a hasNext()method. Since having a class that only implements one of these methods is no use, splitting this interface is not a good idea here.

因此,作为一个通用准则,可以说:如果只向客户端代码公开单个方法的类可能对某些客户端有用,那么为该方法使用单个方法接口是一个好主意。一个反例是Iterator接口:在这里,只有一个next()方法没有方法是没有用的hasNext()。由于拥有一个只实现这些方法之一的类是没有用的,所以在这里拆分这个接口并不是一个好主意。

Example:

例子:

interface SingleMethod{ //The single method interface
    void foo(int i);
}

class X implements SingleMethod { //A class implementing it (and probably other ones)
    void foo(int i){...}
}

class Y { //An unrelated class that has methods with matching signature
    void bar(int i){...}
    static void bar2(int i){...}
}

class Framework{ // A framework that uses the interface
    //Takes a single method object and does something with it
    //(probably invoking the method)
    void consume(SingleMethod m){...}
}

class Client{ //Client code that uses the framework
    Framework f = ...;
    X x = new X();
    Y y = new Y();
    f.consume(x); //Fine, also in Java 7

    //Java 8
    //ALL these calls are only possible since SingleMethod has only ONE method!
    f.consume(y::bar); //Simply hand in a method. Object y is bound implicitly
    f.consume(Y::bar2); //Static methods are fine, too
    f.consume(i -> { System.out.println(i); }) //lambda expression. Super concise.

    //This is the only way if the interface has MORE THAN ONE method:
    //Calling Y.bar2 Without that closure stuff (super verbose)
    f.consume(new SingleMethod(){
         @Override void foo(int i){ Y.bar2(i); }
    });
}

回答by Simon Forsberg

Interfaces with only one (or few) methods is the key to the highly useful Strategy pattern, which is "some design standard which advocates the use of these type of interfaces".

只有一种(或少数)方法的接口是非常有用的策略模式的关键,它是“一些提倡使用这些类型接口的设计标准”。

Another common scenario is when you want a callback. Foo calls Bar as an asynchronous task, and when Bar is finished with something, the result is sent back to Foo using a callback -- which can be an interface containing only one method. (An example of this is the many listeners in Android, Event Listeners in Swing...)

另一种常见的情况是当您需要回调时。Foo 将 Bar 作为异步任务调用,当 Bar 完成某些操作时,结果将使用回调发送回 Foo —— 可以是仅包含一个方法的接口。(这方面的一个例子是 Android 中的许多侦听器,Swing 中的事件侦听器......)

Also, if you have two classes that are tightly coupled with one another (let's call them Foo and Bar). Foo uses nearly all of Bar's methods, but Bar only needs some a few of those from Foo. Foo can implement FooInterfacewhich is then sent to Bar. Now the coupling is looser, because Bar only knows about the FooInterface, but does not care about the other methods the implementing class contains.

此外,如果您有两个紧密耦合的类(我们称它们为 Foo 和 Bar)。Foo 使用了几乎所有 Bar 的方法,但 Bar 只需要一些来自 Foo 的方法。Foo 可以实现FooInterface,然后将其发送到 Bar。现在耦合更松散了,因为 Bar 只知道 FooInterface,而不关心实现类包含的其他方法。

回答by default locale

In what scenarios does it make sense to keep single method interfaces?

在什么情况下保持单一方法接口有意义?

In such a scenarios when you need an interface with only one method.

在这种情况下,您只需要一个方法的接口。

Interfaces are used to encapsulate a common behavior of several classes. So if you have several places in your code where you need to call only limited set of class methods, it's time to introduce an interface. The number of methods depends on what exactly do you need to call. Sometimes you need onemethod, sometimes twoor more, sometimes you don't need methods at all. What matters is that you can separate behavior from implementation.

接口用于封装几个类的共同行为。因此,如果您的代码中有几个地方只需要调用有限的一组类方法,那么是时候引入接口了。方法的数量取决于您究竟需要调用什么。有时您需要一种方法,有时需要两种多种方法,有时您根本不需要方法。重要的是您可以将行为与实现分开。

回答by rai.skumar

Favor Composition over Inheritancetutorial of Head First Design Patternbook recommends this approach to add functionality dynamically to a class. Let's take below case:

Favor Composition over InheritanceHead First Design Pattern本书的教程推荐使用这种方法向类动态添加功能。让我们看下面的案例:

public interface Quackable {
   public void quack();
} 

public class Quacks implements Quackable {
   public void quack(){
       //quack behavior
   }
}

public class DontQuack implements Quackable {
     public void quack(){
         //dont quack
    }
}

public class QuackableDuck{
    Quackable quack;  //add behavior dynamicall

}

So QuackableDuck class can add feature dynamically.

因此 QuackableDuck 类可以动态添加功能。

   quack = new Quacks();
   //or 
   quack = new DontQuack();

So similarly you can add multiple behavior to the class dynamically.

因此,类似地,您可以动态地向类添加多个行为。

回答by Luigi Cristalli

You create interfaces not according to the number of methods in it but to define behaviour expected by components of your systems to deliver a single responsibility to their neighbors. If you follow this simple principle/rule, you might or might not end up with single method interfaces, depending on the responsibility you are defining. I like to keep tests stupid simple and the application very flexible so I usually have many of those

您创建接口不是根据其中的方法数量,而是定义系统组件期望的行为,以将单一责任交付给它们的邻居。如果您遵循这个简单的原则/规则,您可能会或可能不会得到单一方法接口,这取决于您定义的职责。我喜欢让测试变得愚蠢简单,应用程序非常灵活,所以我通常有很多