2017-02-17 2 views
0

У меня есть сторонняя библиотека, которая имеет кучу интерфейсов и сборщиков для создания объектов, реализующих интерфейсы. Эти сконструированные объекты затем передаются в контейнеры. Затем у меня есть интерфейс в моем приложении, который я хочу добавить к объекту, возвращенному из компоновщика.Добавление интерфейса к существующему объекту

Третья сторона

interface ThirdParty1 { ... } 
interface ThirdParty2 { ... } 
class Builder { 
    ... 
    public ThirdParty1 build() { ... } 
} 
class ThirdPartyContainer { 
    void append(ThirdParty1 toAdd) { ... } 
    ThirdParty1 take() { ... } 
} 

Мое приложение

interface MyInterface { ... } 
class MainBody { 
    ThirdPartyContainer queue; 

    MainBody() { 
    ThirdParty1 foo = new Builder().build(); 
    // something to add implementation of MyInterface to foo 
    queue.append(foo); 
    } 

    void calledLater() { 
    ThirdParty1 bar = queue.take(); 
    if (bar instanceof MyInterface) { 
     // do something 
    } else if (bar instanceof ThirdParty2) { 
     // do something else 
    } 
    } 
} 

Я знаю, что я мог бы построить класс-оболочку, которая реализуется ThirdParty1 и MyInterface и взял экземпляр ThirdParty который все вызовы, где пересылаются. Однако это означает, что если Builder.build возвращает что-то, что является реализацией ThirdParty1 и ThirdParty2, реализация ThirdParty2 будет потеряна оболочкой.

Я ожидаю, что то, что я за этим, невозможно, но, будучи довольно новым для Java и всей Магии, которую можно сделать, я не был уверен.

+0

Не совсем, нет. Java не является динамическим языком, где такие вещи возможны и даже рекомендуются. Может быть более удобное решение, чем обертка, если вы объясните свой вариант использования. – Kayaman

+0

В моей работе используется карта, индексированная по ссылке, возвращенной от строителя, к объектам, реализующим MyInterface, это прекрасно работает, но я надеялся, что Java может позволить более элегантное решение, которое предотвратило бы необходимость раскрытия этой карты. Спасибо – lachlan

ответ

0

Как то, что я хочу, это не представляется возможной работу вокруг либо сделать обертку:

class Wrapper implements ThirdParty1, MyInterface 
{ 
    private ThirdParty1 original; 
    Wrapper(ThirdParty1 original_) { original=original_; } 
    // all implemented functions from ThirdParty call said method on original 
} 

Это означает, что, когда передается обратно в библиотеку третьей стороны объект может рассматриваться только как реализация ThirdParty1, таким образом, оптимизация может не произойти. Его также немного боль, чтобы написать весь код пересылки, если у ThirdParty1 было много методов.

В качестве такой альтернативы и метод, мы должны были взять было отображение т.е.

class MainBody { 
    Map<ThirdParty1, MyInterface> remapper; 
    ThirdPartyContainer queue; 
    MainBody() { 
    ThirdParty1 foo = new Builder().build(); 
    remapper.push(foo, new MyInterface() { ... }); 
    queue.append(foo); 
    } 

    void calledLater() { 
    ThirdParty1 bar = queue.take(); 
    MyInterface ours = remapper.get(bar); 
    if (ours != null) { 
     // do something 
    } else if (bar instanceof ThirdParty2) { 
     // do something else 
    } 
    } 
} 

Проблема с этим решением является то, что карта должна быть доступна всем, что делает взгляд вверх. Также наблюдается поразительная оценка карты.

1

Просто реализуйте свой собственный строитель, который строит экземпляры вашего MyInterface и передает эти объекты в очередь.

+0

Это не сработает, так как новые объекты будут просто реализовывать MyInterface, а не ThirdParty1 или ThirdParty2. Как уже упоминалось в исходном вопросе, может быть реализован класс wrapper/forwarder, но он будет реализовывать только MyInterface и ThirdParty1, скрывая ThirdParty2 или любые другие интерфейсы, в которые также был реализован возвращенный объект. – lachlan

+0

Очевидно, что 'MyInterface' должен расширять' ThirdParty1' и 'ThirdParty2'. – Divers

+0

Это будет работать, если бы я знал все интерфейсы, что возвращаемое значение при реализации, но как только это неизвестно, оно не может быть жизнеспособным решением. – lachlan

Смежные вопросы