24

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

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

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

4

5 回答 5

19

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

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

例子:

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); }
    });
}
于 2013-03-04T11:43:28.630 回答
5

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

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

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

于 2013-03-04T11:24:36.590 回答
0

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

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

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

于 2013-03-04T11:35:58.610 回答
0

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

}

所以 QuackableDuck 类可以动态添加特征。

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

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

于 2013-03-04T11:47:30.643 回答
0

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

于 2017-12-21T06:50:21.953 回答