没有传递依赖的适配器和模块化

时间:2015-09-18 09:29:17

标签: dependencies osgi adapter modularization

我遇到过几次以下情况,我找不到一个完全令人满意的解决方案:

我正在使用OSGi开发Java应用程序,并且遵循OSGi的最佳实践,它是高度模块化的。这是我的一些插件和类的摘录:

- com.example.core.db.manager (plugin)
    |- com.example.core.db.manager (package)
         |- DatabaseManager (interface)

- com.example.core.business.objectmanager (plugin)
    |- com.example.core.business.objectmanager (package)
         |- BusinessObjectManager (interface)

- com.example.some.businessobjectmanager.consumer (plugin)
    |- com.example.some.businessobjectmanager.consumer (package)
         |- SomeBusinessObjectManagerConsumer (interface)
            (obviously this is not the real name, but the name is irrelevant)

其中

  • DatabaseManager是一个与数据库直接交互的低级构造。
  • BusinessObjectManager是一个高级别的构造,在其中起作用 其他事情)作为DatabaseManager的一种适配器。
  • SomeBusinessObjectManagerConsumer使用BusinessObjectManager并且不应该知道底层数据库,甚至不知道数据库。它应该了解DatabaseManager;相反,它应该只与BusinessObjectManager
  • 进行交互

到目前为止一切顺利。但是现在SomeBusinessObjectManagerConsumer需要更新数据库中实体之间的一些边缘(我使用graph database,这意味着我的实体(通常是表中的行)是节点,它们之间的关系是边缘)。如前所述,SomeBusinessObjectManagerConsumer对数据库一无所知,但它知道有一些“业务对象”(节点),并且其中一些(边缘)之间存在链接。

BusinessObjectManager中,我创建了一个方法replaceLinks,如下所示......

UpdatedLinks replaceLinks(BusinessObjectUID from, Set<BusinessObjectUID> to);

...这应该确保在返回时,from业务对象只会链接到to个对象,可能会删除以前的链接并添加新的链接。我想知道这些删除和添加。我在插件UpdatedLinks中创建了一个界面com.example.core.business.objectmanager

public interface UpdatedLinks {
    Set<BusinessObjectUID> getRemovedLinks();
    Set<BusinessObjectUID> getAddedLinks();
}

BusinessObjectManager并不是真正要执行此链接替换并将UpdatedLinks返回对象放在一起的人。相反,它将此委托给DatabaseManager。因此,我在DatabaseManager中创建了一个等效方法,而BusinessObjectManager只会调用此方法。

现在的问题是放置接口UpdatedLinks的位置:DatabaseManagerBusinessObjectManagerSomeBusinessObjectManagerConsumer需要它,但这些类之间的依赖关系(及其对应的)插件)朝着这个方向前进:

SomeBusinessObjectManagerConsumer ---depends-on---> BusinessObjectManager ---depends-on---> DatabaseManager

所以:

  • 我无法将UpdatedLinks放入BusinessObjectManager的插件中,因为DatabaseManager无法看到它。
  • 我无法将其放入DatabaseManager的插件中,因为SomeBusinessObjectManagerConsumer无法看到它(请记住SomeBusinessObjectManagerConsumerDatabaseManager一无所知;因为OSGi中的模块化,如果我声明对它的显式依赖,它只能访问DatabaseManager,我不想这样做。
  • 它太具体了,不能把它放在某种“实用程序”插件中。
  • 我目前没有任何插件可以放置此界面,这将使所有相关插件可用。

基本上,我必须为这个接口创建一个新的插件,我甚至找不到该插件的任何有意义的名称,考虑谁将依赖它。 (但主要是,我反对为这个界面创建一个插件的想法,它只是作为一种传递replaceLinks方法的结果的方式。)

我已经多次遇到这种情况(特别是最近使用OSGi,因为模块化),我永远找不到完全令人满意的解决方案。在这种情况下你会做什么/做什么?

“Meta”免责声明:

  • 标题可能更好;我只是想不出更好的一个。随意改变它。
  • 我不确定stackoverflow对于这个问题是否是正确的StackExchange社区,所以请随意推荐其他可能更合适的社区。我找不到更好的。
  • 我试图详细解释,以便您可以了解情况。我希望我没有过头;)

1 个答案:

答案 0 :(得分:1)

我建议简单地为它创建两个接口。一个是BusinessObjectManager使用的DataBaseManager级别,另一个是SomeBusinessObjectManagerConsumer使用的BusinessObjectManager级别。

由于您希望底层和顶层不连接,因此您也不应共享它们之间的接口。当然你也可以为此创建一个特殊的api包,但我认为它不值得,并且会伤害每层api的凝聚力。