0

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::doTheGreetingGreeter 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.

Antwort

0

Ich suchte weiter nach einer Antwort, aber es scheint keine Lösung zu geben, die eine Anmerkung verwendet. Bei der Frage hatte ich jedoch einen speziellen Anwendungsfall im Sinn: Ich möchte viele verschiedene Implementierungen derselben funktionalen Schnittstelle in einer einzigen Datei aufschreiben.Tatsächlich gibt es eine Lösung für dieses Problem, das auch hervorragend mit automatischen Refactoring-Tools arbeitet:

public interface Greeter { 
    String greet(); 
} 

public enum EnumGreeterImpl implements Greeter { 
    GREETER1 { 
     @Override 
     public String greet() { 
      return "Hello World!"; 
     } 
    }, 
    GREETER2 { 
     @Override 
     public String greet() { 
      return "Foo bar"; 
     } 
    }, 
} 

private void run() { 
    Greeter foo = EnumGreeterImpl.GREETER1; 
    System.out.println(foo.greet()); 
} 

Siehe auch:

0

Ja: Sie müssen die Schnittstelle implementieren. Wenn Sie eine Anmerkung hinzufügen können, die mit der Schnittstelle verknüpft, warum nicht Ihre Klasse implementieren es?

+0

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. –

Verwandte Themen