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

Nar*_*hai 21 java oop design-patterns interface

我在许多图书馆见过像Spring它使用了大量的接口,与单一的方法在他们像BeanNameAware等.

实现者类将使用单个方法实现许多接口.

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

gex*_*ide 15

使用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); }
    });
}
Run Code Online (Sandbox Code Playgroud)

  • `f.consume(i - > {System.out.println(i);})`可以总结如下:`f.consume(System.out :: println);` (5认同)

Sim*_*erg 5

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

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

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

  • 我想说,战略模式本身就足够了。但我可以尝试扩大答案。 (2认同)
  • 优点之一将是为下一个Java中的lambda表达式做好准备。 (2认同)