betrachten das folgende Beispiel zu unterstützen:Annotation refactoring eine funktionelle Schnittstelle
public interface Greeter {
String greet();
}
public class ExplicitGreeterImpl implements Greeter {
@Override
public String greet() {
return "Hello World!";
}
}
public class ImplicitGreeterImpl {
public String doTheGreeting() {
return "Hello World!";
}
}
private void run() {
System.out.println(new ExplicitGreeterImpl().greet());
Greeter foo = new ImplicitGreeterImpl()::doTheGreeting;
System.out.println(foo.greet());
}
Die funktionale Schnittstelle Greeter
hat zwei Implementierungen. ExplicitGreeterImpl
implementiert mit dem implements
-Klausel, während ImplicitGreeterImpl::doTheGreeting
Greeter
ohne es implementiert. Nichtsdestoweniger ist ImplicitGreeterImpl::doTheGreeting
entworfen, um Greeter
zu implementieren, genau wie ExplicitGreeterImpl
.
Nun, ich möchte die Greeter
Schnittstelle Refactoring, so kann ich einen Namen zu übergeben:
public interface Greeter {
String greet(String name);
}
ich dies mit dem Eclipse bereitgestellt Refactoring ändern Methode Unterschrift tun kann (ich bin sicher, dass andere IDEs haben ein ähnliches Refactoring). Dies aktualisiert automatisch alle Implementierungen und Verwendungen der Schnittstelle . Implementierungen erhalten den neuen Parameter, während Nutzungen einen konfigurierbaren Standardwert übergeben. Dies funktioniert gut für die ExplicitGreeterImpl
, aber das Refactoring berührt nicht die ImplicitGreeterImpl::doTheGreeting
Methode. Somit ist die Zuordnung
Greeter foo = new ImplicitGreeterImpl()::doTheGreeting;
wird zu einem Fehler bei der Kompilierung. Um das zu beheben, muss ich die Signatur der Methode ImplicitGreeterImpl::doTheGreeting
manuell anpassen.
Jetzt verstehe ich, dass es in vielen Fällen unerwünscht ist, die Signatur von ImplicitGreeterImpl::doTheGreeting
automatisch anzupassen. Allerdings glaube ich, dass der aktuelle Workflow verbessert werden kann:
- Eklipse keine Warnung in der Refactoring Vorschau anzuzeigen, dass es schlägt vor, wird ein Fehler bei der Kompilierung sein.
- Es sollte möglich sein, die Methode mit Anmerkungen zu versehen, um zu verdeutlichen, dass sie eine gegebene funktionale Schnittstelle implementieren soll.
Zum Beispiel ImplicitGreeterImpl
könnte wie folgt aussehen:
public class ImplicitGreeterImpl {
@Implements(Greeter.class)
public String doTheGreeting() {
return "Hello World!";
}
}
Nun Refactoring-Tools können sicher sein, dass ImplicitGreeterImpl::doTheGreeting
sollten Greeter
implementieren und somit kann sie automatisch die Signatur ändern.
Also meine Frage ist: Gibt es eine Möglichkeit, Refactoring-Tools zu sagen, dass eine bestimmte Methode eine bestimmte funktionale Schnittstelle implementieren soll? Ich suchte nach der oben vorgeschlagenen Anmerkung, fand aber nichts Nützliches.
Es ist eigentlich eine gute Grund, die Schnittstelle nicht direkt zu implementieren, sondern die Methodenreferenz zu verwenden. Betrachten Sie das Befehlsmuster. In diesem Fall: (1) Die Befehlsschnittstelle ist wahrscheinlich eine funktionale Schnittstelle, (2) es gibt viele Implementierungen der Befehlsschnittstelle und (3) jede dieser Implementierungen ist sehr einfach. Das Hinzufügen einer zusätzlichen Klasse für jede dieser Implementierungen fügt dem Code eine Menge Rauschen hinzu. Wenn jedoch jede Befehlsimplementierung nur eine Methode ist, wird der Code viel sauberer. –