向现有对象添加接口

问题描述:

我有一个第三方库,它有一堆接口和构建器来构造实现接口的对象。这些构造的对象然后被传递到容器中。然后我在我的应用程序中有一个接口,我想将这个接口添加到从构建器返回的对象中。向现有对象添加接口

第三方

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的,把第三方的实例的包装类,其中转发到所有通话。然而,这意味着如果Builder.build返回的是ThirdParty1和ThirdParty2的实现,那么ThirdParty2实现将被封装器丢失。

我希望我所追求的是不可能的,但是对于Java和所有可以完成的魔法来说相当新颖,我并不确定。

+0

不是,不。 Java不是一种动态语言,在这种情况下,这些东西是可能的,甚至是推荐的用法如果你进一步解释你的用例,可能会比封装更方便。 – Kayaman

+0

我的工作使用一个映射索引在从构建器返回的引用上实现MyInterface的对象,这工作正常,但我希望Java可能允许一个更优雅的解决方案,将防止需要公开该映射。谢谢 – lachlan

,因为我想什么是不可能的解决办法要么做一个包装:

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

这种解决方案的问题在于,地图必须对任何正在做的查询访问。还有查看地图的性能影响。

只需实施您自己的构建器,它将构建您的MyInterface的实例并将该对象放入队列中。

+0

这不会工作,因为新的对象只会实现MyInterface,而不是ThirdParty1或ThirdParty2。正如在原始问题中提到的,可以实现包装器/转发器类,但只会实现MyInterface和ThirdParty1,隐藏ThirdParty2或任何其他接口,其中也实现了返回的对象。 – lachlan

+0

显然'MyInterface'应该扩展'ThirdParty1'和'ThirdParty2'。 – Divers

+0

如果我完全了解所有返回值在哪里实现的接口,但是一旦知道它就不能成为可行的解决方案,那么这将起作用。 – lachlan