2017-02-17 3 views
0

Ich habe eine Third-Party-Bibliothek, die eine Reihe von Schnittstellen und Buildern zum Konstruieren von Objekten aufweist, die die Schnittstellen implementieren. Diese konstruierten Objekte werden dann in Container übergeben. Ich habe dann eine Schnittstelle in meiner Anwendung, der ich eine Implementierung von einem Objekt hinzufügen möchte, das von dem Generator zurückgegeben wird.Schnittstelle zum vorhandenen Objekt hinzufügen

Third Party

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

Meine Anwendung

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 
    } 
    } 
} 

Ich weiß, ich könnte eine Wrapper-Klasse erstellen, die ThirdParty1 und MyInterface umgesetzt und nahm eine Instanz von Drittanbietern, die alle Anrufe, bei denen weitergeleitet. Dies bedeutet jedoch, dass, wenn Builder.build etwas zurückgibt, das eine Implementierung von ThirdParty1 und ThirdParty2 ist, die ThirdParty2-Implementierung vom Wrapper verloren gehen würde.

Ich erwarte, was ich nachher nicht möglich bin, aber ziemlich neu zu Java und all die Magie, die getan werden kann, war ich nicht sicher.

+0

Nicht wirklich, nein. Java ist keine dynamische Sprache, in der solche Dinge möglich und sogar empfohlen wären. Es kann eine bequemere Lösung als ein Wrapper geben, wenn Sie Ihren Anwendungsfall weiter erläutern. – Kayaman

+0

Meine Arbeit verwendet eine Map, die auf den vom Builder generierten Verweis auf Objekte verweist, die MyInterface implementieren, das funktioniert gut, aber ich hatte gehofft, dass Java eine elegantere Lösung zulässt, die das Aufdecken dieser Map verhindern würde. Danke – lachlan

Antwort

0

Wie, was ich will nicht möglich ist, die Arbeit um machen entweder einen Wrapper:

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

Dies bedeutet, dass, wenn sie in der Dritten Bibliothek zurückgegeben kann das Objekt nur als ThirdParty1 Implementierung behandelt werden, somit könnten Optimierungen nicht stattfinden. Es ist auch ein bisschen mühsam, den gesamten Weiterleitungscode zu schreiben, wenn ThirdParty1 viele Methoden hatte.

Als solche ist die Alternative und Methode, die wir nehmen mussten, war Mapping heißt

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 
    } 
    } 
} 

Das Problem bei dieser Lösung ist, dass die Karte etwas zugänglich sein muss, dass die Lookup tut. Es gibt auch einen Leistungseinbruch beim Nachschlagen der Karte.

1

Implementieren Sie einfach Ihren eigenen Builder, der Instanzen Ihres MyInterface erstellt und diese Objekte in der Warteschlange übergibt.

+0

Das würde nicht funktionieren, da die neuen Objekte nur MyInterface, nicht ThirdParty1 oder ThirdParty2 implementieren würden. Wie in der ursprünglichen Frage erwähnt, könnte eine Wrapper/Forwarder-Klasse implementiert werden, würde aber nur MyInterface und ThirdParty1 implementieren, ThirdParty2 oder andere Schnittstellen ausblenden, die das zurückgegebene Objekt ebenfalls implementiert hat. – lachlan

+0

Offensichtlich sollte 'MyInterface'' ThirdParty1' und 'ThirdParty2' erweitern. – Divers

+0

Das würde funktionieren, wenn ich volle Kenntnisse über alle Schnittstellen hätte, die der zurückgegebene Wert implementiert, aber sobald dies nicht bekannt ist, ist es keine brauchbare Lösung. – lachlan

Verwandte Themen