views:

207

answers:

3

I have a number of collections of classes which I need to refactor into new classes. I'm using Java with either Eclipse or Netbeans. Currently I create the new class FooList with a delegate List<Foo> and then follow all the places where the code fails to compile. Is there a way to do this without breaking the code (and preferably a single operation)?

EDIT I have the following type of construct:

public static List<Foo> Bar.createFooList(String s)

and List<Foo> gets used frequently elsewhere and it makes sense as a business object FooList. I have done this manually by:

public class FooList {
    private List<Foo> fooList;
    public FooList(String s) {
        createList(s);
    }
    private void createList(String s) {//...}
    public int size() {return fooList.size();}
}

FooList will also have methods beyond List. For example the present:

Bar.normalize(List<Foo> fooList);

would then become

fooList.normalize();

Where another function needs the methods of List I used the Source|Generate Delegate Methods option in Eclipse to generate those methods in FooList (as with size() above).

I can see the attraction @JonSkeet of implementing List<Foo> but I can't see how to change all my code automatically.

+7  A: 

Is there any reason not to make FooList implement List<Foo>?

Jon Skeet
I can't think of any example where I would implement List or other interface. ListOfEmployee mustn't implement List<Employee>.
Mykola Golubyev
Then it's a very misleading name. Why would a `ListOfEmployee` *not* be a `List<Employee>`? It's entirely unclear what you're trying to achieve with your `ListXXX` class which isn't *actually* a `List`
Jon Skeet
There are two "list". First - interface. Second - you business object. They don't have to be the same. And in most cases 'second' just use 'first'. For example I can leave only certain methods in my ListXXX or attach some aspects.
Mykola Golubyev
+3  A: 

You have List<Foo> which is an expressive representation of the list of Foes. The only reason I can see for get ridding of the List<Foo> is to limit or to control some access List operations.

In case of limit - you can't inherit from List<Foo> and in general there is no good cases to inherit List except of custom List for custom algorithms creation.

As I understand Foo is some business object. ListOfFoo in this case has to remain as business object and not as List.

In case of control - do delegation as you do. Eclipse or Netbeans are your friends in this process.

But think again. List<Foo> is already a good looking peace of information. It is not the same as C++ std::list<Foo> which you have to wrap either way.

Mykola Golubyev
+1  A: 

I just tried this out in IntelliJ, and didn't see anything that a direct refactor. But this may do it:

  1. Create your FooList like so:

    public abstract class BarList implements List<Bar> {}

  2. Do a global search and replace of "List<Foo>" with your "FooList".

  3. Now you are off to the races.

You can now use the refactorings you have available, like (IntelliJ's) "Replace Constructor with Factory Method", etc.

Does that work?

ndp
Thanks - this is the sort of thing I was looking for. I'll see what Eclipse can do
peter.murray.rust
I guess I left off the step 4, 5, 6... which is ultimately to remove the "implements List<Bar>" from your BarList. It becomes a non-abstract class, and you add needed methods one at a time. Once you've done your other refactors you should be able to just remove the implements/extends List<Bar>.
ndp