我在很多像Spring
这样的库中看到过,它们使用了很多接口,其中包含单一方法,如BeanNameAware
等。
实现者类将使用单个方法实现许多接口。
在哪些情况下保留单个方法接口是有意义的?这样做是为了避免使单个界面变得笨重,例如ResultSet
?或者是否有一些设计标准主张使用这些类型的接口?
答案 0 :(得分: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); }
});
}
答案 1 :(得分:4)
只有一个(或几个)方法的接口是非常有用的Strategy pattern的关键,这是“一些主张使用这些类型接口的设计标准”。
另一种常见情况是您需要回调。 Foo将Bar称为异步任务,当Bar完成某些操作时,结果将使用回调发送回Foo - 这可以是仅包含一个方法的接口。 (这方面的一个例子是Android中的许多监听器,Swing中的事件监听器......)
另外,如果你有两个彼此紧密耦合的类(让我们称它们为Foo和Bar)。 Foo几乎使用了Bar的所有方法,但Bar只需要一些来自Foo的方法。 Foo可以实现FooInterface
,然后发送到Bar。现在耦合更宽松,因为Bar只知道FooInterface,但不关心实现类包含的其他方法。
答案 2 :(得分:0)
在哪些情况下保留单个方法接口是有意义的?
在这种情况下,只需要一个只有一种方法的界面。
接口用于封装多个类的常见行为。因此,如果您的代码中有多个位置只需要调用有限的类方法,那么就应该引入一个接口了。方法的数量取决于您需要调用什么。有时您需要one方法,有时候需要two或more,有时候需要don't need methods at all。重要的是,您可以将行为与实施分开。
答案 3 :(得分:0)
Favor Composition over Inheritance
书籍的 Head 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();
因此,您可以动态地向类中添加多个行为。
答案 4 :(得分:0)
您不是根据其中的方法数创建接口,而是定义系统组件所期望的行为,以便向其邻居提供单一责任。如果您遵循这个简单的原则/规则,您可能会或可能不会使用单个方法接口,具体取决于您定义的职责。我喜欢保持测试简单愚蠢,应用程序非常灵活,所以我通常有很多