2011-01-07 17 views
5

Tengo una colección de clases concretas que definen una API, y me gustaría extraer la interfaz de estas clases (es decir, esencialmente la jerarquía de tipos y los métodos públicos) de la la implementación real de la API.Manera automatizada para extraer interfaces de una clase de Java

Así por ejemplo, si una de las clases públicas en la API es

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 */ 

} 

quisiera entrar en una interfaz y una implementación

es decir

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

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

y

¿Existe alguna herramienta que pueda usar para hacer esta separación de manera automática, o estoy va a tener que rodar mi propio programa para hacer el trabajo? Debe ser una herramienta que requiera una interacción mínima.

Respuesta

5

¡Encontré la solución!

Eclipse, tiene soporte para la refactorización de scripts, los scripts están en xml pero no son muy amigables para el ser humano, pero he generado los scripts de todos modos que hacen que eclipse realice toda la refactorización.

Para los detalles de refactorización guión eclipse, look here y utilizar Eclipse para generar algunos ejemplos para usted para que sepa lo que el guión debe ser similar

+0

Esto es precisamente lo que estaba buscando (¡tengo el escenario exacto que mencionas)! ¿Alguna posibilidad de que puedas compartir el script de refactorización que usaste? Voy a spelunk en Eclipse para resolver esto, pero podría usar cualquier ayuda. ¡Gracias por adelantado! – scorpiodawg

+0

Wow, el XML generado en el "script" no es bonito (a partir de Eclipse Indigo). Informará si obtengo algo útil de esto. – scorpiodawg

3

Muchos IDE, como IntelliJ, tienen un comando "Extraer Interface", que lleva a cabo una refactorización para usted: http://www.jetbrains.com/idea/features/refactoring.html#Extract_Interface

+1

¿Puede funcionar en múltiples archivos a la vez? Digamos que seleccionar todas las clases en un paquete y realizar la extracción de interfaz? – hhafez

+1

Si está haciendo esto en todos los archivos por el bien de la "pureza", le sugiero que reconsidere qué beneficio está obteniendo realmente. Personalmente, extraía la interfaz donde y cuando tenía sentido y dejo todo lo demás tal como está. Pero entonces, no sé tu razonamiento. – Synesso

+0

No es por el bien de la "pureza" y no será para todas las clases, pero sería tedioso hacerlo uno por uno. – hhafez

1

Estoy bastante seguro de que tendrá que rodar su propia herramienta para hacer este trabajo; no es algo que muchos desarrolladores utilizarían, y quienes lo usaban no lo usarían con frecuencia. Extract Interface, para ser hecho correctamente, realmente necesita inteligencia (del tipo real) para guiarlo. Una herramienta que extrajera ciegamente todos los elementos públicos & protegidos, y construyera ciegamente una jerarquía de interfaz para reflejar una jerarquía de implementación, está lejos de ser inteligente, y el producto final no sería bonito. Desarrollar la inteligencia (artificial) para tomar buenas decisiones sobre qué incluir y qué liderar, sería una herramienta útil, pero confieso que es inimaginablemente difícil para mí. Lo que ofrece IDEs actuales - asistencia guiada - es probablemente el mejor compromiso. Alegrarse; ¡es muchísimo menos tedioso que hacer cada paso a mano!

+0

Estoy de acuerdo en general que la salida no sería bonita, pero es un punto de partida y simplemente es lo que necesito en esta situación particular (la API que quiero refractor en realidad se autogenera desde otra herramienta, por lo que la estructura es en realidad bien definido y, por lo tanto, la herramienta de refactorización puede ser bastante inteligente en este caso) – hhafez

3

javap, una herramienta en el JDK, te llevará más de lo que querer. Sin embargo, prepárate para que no maneje algunas cosas correctamente. Lo siento, olvido qué, tal vez anotaciones, clases internas, algo así.

Si la incrustación en javap es el propietario de Java aplicación ayudaría, se puede hacer algo como esto:

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(); 
    } 

tal fin es necesario tools.jar JDK de Sun en la ruta de clase.

Cuestiones relacionadas