2011-01-07 1 views
5

Ich habe eine Sammlung von konkreten Klassen, die eine API definieren, und ich möchte die Schnittstelle dieser Klassen extrahieren (dh im Wesentlichen die Typhierarchie und öffentliche Methoden) von der tatsächliche Implementierung der API.Automatisierte Möglichkeit, Interfaces aus einer Java-Klasse zu extrahieren

So zum Beispiel, wenn eine der öffentlichen Klassen in der API ist

public class Foo extends Bar { 
    /* some fields which I don't care about */ 

    public void method() { 
    /* implementation here */ 
    } 

    public void otherMethod() { 
    /* implementation goes here */ 
    } 

    /* some non public methods which I don't care about */ 

} 

Ich möchte in eine Schnittstelle brechen und eine Implementierung

dh

public interface FooInterface extends BarInterface { 
    public void method(); 
    public void otherMethod() 
} 

public class Foo implements FooInterface { 
    /* etc etc */ 
} 

und

Gibt es ein Werkzeug, das ich verwenden kann, um diese Trennung auf automatisierte Weise zu tun, oder bin ich werde ich mein eigenes Programm drehen müssen, um den Job zu machen? Es muss ein Werkzeug sein, das nur minimale Interaktion erfordert.

Antwort

5

Ich fand die Lösung!

Eclipse, hat Unterstützung für Refactoring-Skripte, die Skripte sind in XML noch nicht sehr menschlich freundlich, aber ich habe die Skripte sowieso generiert, die Eclipse macht alle Refactoring durchführen.

Einzelheiten Eclipse Skript Refactoring, look here und verwenden Eclipse einige Beispiele für Sie zu erzeugen, so dass Sie wissen, was das Skript wie

+0

Genau das habe ich gesucht (ich habe das genaue Szenario, das du erwähnst)! Können Sie das von Ihnen verwendete Refactoring-Skript teilen? Ich werde in Eclipse spelunkieren, um das herauszufinden, aber ich könnte jede Hilfe gebrauchen. Danke im Voraus! – scorpiodawg

+0

Wow, das im "Skript" erzeugte XML ist nicht schön (wie von Eclipse Indigo). Meldet sich zurück, wenn ich etwas Nützliches daraus schaffe. – scorpiodawg

3

Viele IDEs, wie IntelliJ, haben eine „Extract Interface“ Befehl, der für Sie ein Refactoring durchführt: http://www.jetbrains.com/idea/features/refactoring.html#Extract_Interface

+1

Kann es mehrere Dateien gleichzeitig verarbeiten? Sagen wir mal, wählen Sie alle Klassen in einem Paket und führen Sie die Interface Extraction durch? – hhafez

+1

Wenn Sie dies aus Gründen der "Reinheit" für alle Dateien tun, schlage ich vor, Sie überdenken, welchen Nutzen Sie tatsächlich gewinnen. Persönlich würde ich die Schnittstelle extrahieren, wo und wann es Sinn ergab und alles andere so lassen wie es ist. Aber dann kenne ich deine Argumentation nicht. – Synesso

+0

Es ist nicht wegen "Reinheit" und es wird nicht für jede Klasse sein, aber es wäre zu mühsam, eins nach dem anderen zu tun. – hhafez

1

Ich bin ziemlich sicher, werden Sie Ihr eigenes Tool zu tun, um diesen Job rollen müssen; Es ist nicht etwas, was viele Entwickler verwenden würden, und diejenigen, die es benutzt haben, würden es nicht oft benutzen. Extract Interface, um richtig gemacht zu werden, braucht wirklich Intelligenz (die wirkliche Art), die es leitet. Ein Tool, das blind alle öffentlichen geschützten Elemente extrahiert und blind eine Schnittstellenhierarchie zum Spiegeln einer Implementierungshierarchie erstellt hat, ist alles andere als intelligent, und das Endprodukt wäre nicht hübsch. Die (künstliche) Intelligenz zu entwickeln, um gute Entscheidungen darüber zu treffen, was aufgenommen und was herausgeführt werden soll - das wäre ein nützliches Werkzeug, aber ich gestehe es unvorstellbar schwer für mich. Was aktuelle IDEs bieten - geleitete Hilfe - ist wahrscheinlich der beste Kompromiss. Kopf hoch; es ist massiv weniger mühsam als jeden Schritt mit der Hand!

+0

Ich stimme im Allgemeinen zu, die Ausgabe wäre nicht schön, aber es ist ein Ausgangspunkt und es ist gerade, was ich in dieser besonderen Situation brauche (die API Ich möchte Refraktor ist eigentlich aus einem anderen Werkzeug automatisch generiert, so dass die Struktur tatsächlich ist gut definiert und daher kann das Refactoring-Tool in diesem Fall ziemlich schlau sein) – hhafez

3

javap, ein Werkzeug in das JDK, Sie fast alles, was Sie bekommen, aussehen sollte wollen. Sei jedoch darauf vorbereitet, einige Dinge nicht richtig zu behandeln - sorry, ich vergesse was, vielleicht Anmerkungen, innere Klassen, sowas.

Wenn Einbettung javap in Java App besitzen würde helfen, können Sie etwas tun:

import sun.tools.javap.Main; 
... 
    void javap(String className) throws IOException 
    { 
     bos = new ByteArrayOutputStream(); 
     ourOut = new PrintStream(bos); 

     PrintStream oldOut = System.out; 
     System.setOut(ourOut); 

     String[] params = new String[] {"-public", className}; 
     Main.main(params); 

     System.setOut(oldOut); 

     String str = bos.toString(); 
    } 

Das Sun JDK tools.jar im Classpath erfordert.