8

I've got a collection of concrete Classes which define an API, and I would like to extract the Interface of these classes (ie: essentially the type hierarchy and public methods) from the actual implementation of the API.

So for example if one of the public classes in the API is

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

 }

I would like to break into an interface and an implementation

ie

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

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

and

Is there a tool I can use to do this separation in automated way, or am I going to have to roll my own program to do the job? It needs to be a tool that requires minimal interaction.

Carl Manaster
  • 39,912
  • 17
  • 102
  • 155
hhafez
  • 38,949
  • 39
  • 113
  • 143

4 Answers4

5

I found the solution!

Eclipse, has support for refactoring scripts, the scripts are in xml yet not very human friendly but I have generated the scripts anyway that makes eclipse perform all the refactoring.

For details of eclipse script refactoring, look here and use eclipse to generate a few examples for you so you know what the script should look like

hhafez
  • 38,949
  • 39
  • 113
  • 143
  • This is precisely what I was looking for (I have the exact scenario you mention)! Any chance you can share the refactoring script you used? I'm going to spelunk in Eclipse to figure this out, but I could use any help. Thanks in advance! – scorpiodawg Mar 02 '12 at 20:53
  • Wow, the XML generated in the "script" is not pretty (as of Eclipse Indigo). Will report back if I get something useful out of this. – scorpiodawg Mar 02 '12 at 21:31
3

Many IDEs, like IntelliJ, have an "Extract Interface" command which performs a refactoring for you: http://www.jetbrains.com/idea/features/refactoring.html#Extract_Interface

Adam Vandenberg
  • 19,991
  • 9
  • 54
  • 56
  • 1
    can it work on multiple files at once? Lets say select all classes in a package and perform the Interface Extraction? – hhafez Jan 07 '11 at 04:59
  • 1
    If you're doing this to all files for the sake of "purity" I suggest you rethink what benefit you are actually gaining. Personally, I would extract interface where and when it made sense and leave everything else as is. But then, I don't know your reasoning. – Synesso Jan 07 '11 at 05:02
  • Its not for the sake of "purity" and it wont be for every class, but it would be to tedious to do one by one. – hhafez Jan 07 '11 at 05:05
3

javap, a tool in the JDK, will get you most of what you want. However, be prepared for it to not handle some things correctly - sorry, I forget what, maybe annotations, inner classes, something like that.

If embedding javap in you own Java app would help, you can do something like this:

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

This requires the Sun JDK tools.jar in the classpath.

Ed Staub
  • 15,480
  • 3
  • 61
  • 91
1

I'm pretty sure you'll have to roll your own tool to do this job; it's not something that many developers would use, and those who did use it wouldn't use it often. Extract Interface, to be done right, really needs intelligence (the real kind) guiding it. A tool that blindly extracted all public & protected elements, and blindly built an interface hierarchy to mirror an implementation hierarchy, is far from smart, and the end product wouldn't be pretty. Developing the (artificial) intelligence to make good decisions about what to include and what to lead out - that would be a useful tool, but I confess unimaginably difficult for me. What current IDEs offer - guided assistance - is probably the best compromise. Cheer up; it's massively less tedious than doing every step by hand!

Carl Manaster
  • 39,912
  • 17
  • 102
  • 155
  • I agree in general the output wouldn't be pretty, but it is a starting point and it just happens to be what I need in this particular situation (the API I want to refractor is actually autogenerated from another tool so the structure is actually well defined and hence the refactoring tool can be quite smart in this case) – hhafez Jan 07 '11 at 18:59