何时在 Java 中使用单方法接口
我见过许多库,比如使用很多接口和单一方法,比如,等等。Spring
BeanNameAware
实现器类将使用单个方法实现许多接口。
在什么情况下保留单方法接口是有意义的?例如,这样做是为了避免使单个界面笨重吗?还是有一些设计标准提倡使用这些类型的接口?ResultSet
我见过许多库,比如使用很多接口和单一方法,比如,等等。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可以实现,然后将其发送到Bar。现在耦合更宽松了,因为 Bar 只知道 FooInterface,而不关心实现类包含的其他方法。FooInterface