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

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (19)

我曾经在很多libraries看到过像Spring使用单一方法的很多接口,例如BeanNameAware,等等。

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

在什么情况下保持单个方法接口是有意义的?是否这样做是为了避免让一个单一的接口庞大,例如ResultSet?还是有一些倡导使用这些类型的接口的设计标准?

提问于
用户回答回答于

对于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); }
    });
}
用户回答回答于

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

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

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

扫码关注云+社区