Есть ли лучший / более чистый способ условного создания типа, чем использование instanceof? [Джава] - PullRequest
3 голосов
/ 30 июня 2010

Предположим, у меня есть:

public class FightingZone<MobileSuitso, Background> {

    private MobileSuitCollection<MobileSuitso> msCollection;
    private BackgroundInfo<Background> bgInfo;

    public FightingZone(MobileSuitCollection<MobileSuitso> newCollection, BackgroundInfo<Background> newInfo) {
        this.msCollection = newCollection;
        this.bgInfo = newInfo;
    }

    ...

        ...// inside a method
        MobileSuitCollection temporaryCollection = new MobileSuitCollection<MobileSuitso>(); // /!\

}

Проблема в том, что MobileSuitCollection - это интерфейс, поэтому я не могу его создать. Например, я мог бы сделать:

MobileSuitCollection temporaryCollection = new GundamMeisterCollection<MobileSuitso>();
MobileSuitCollection temporaryCollection = new InnovatorCollection<MobileSuitso>();
MobileSuitCollection temporaryCollection = new CannonFolderCollection<MobileSuitso>();

и т.д.. Однако для манипулирования temporaryCollection мне нужно, чтобы он был того же типа, что и тот, который был передан через параметр в мой класс. Вот я и подумал:

if (msCollection instanceof GundamMeisterCollection) {
    ...
} else if (msCollection instanceof InnovatorCollection) {
    ...
} ...

Однако я понимаю, что это ужасно. Есть лучший способ сделать это? Можно ли сохранить ссылку на класс, используемый начальным типом, а затем создать экземпляр temporaryCollection с этим?

Ответы [ 2 ]

2 голосов
/ 30 июня 2010

Код, который вы помещаете в условие if, можно поместить в Visitor:

// Generics skipped for brevity
interface MobileSuitCollectionVisitor {
   handleCollection(GundamMeisterCollection collection);
   handleCollection(InnovatorCollection collection);
   handleCollection(CannonFolderCollection collection)
}

class ConcreteVisitor implements MobileSuitCollectionVisitor { 
    // place all of the logic in the implemented methods
}

, а затем разрешить MobileSuitCollection иметь метод:

void visit(MobileSuitCollectionVisitor visitor);

И в каждой реализации MobileSuitCollection просто есть

public void visit(MobileSuitCollectionVisitor visitor) {
    visitor.handleCollection(this);
}
0 голосов
/ 30 июня 2010

Быстрый и грязный способ сделать это - клонировать оригинальную коллекцию, а затем манипулировать ею по мере необходимости. Лучшим способом может быть добавление метода newInstance() к интерфейсу или передача фабрики на FightingZone.

...