0

我曾多次遇到以下情况,但找不到完全令人满意的解决方案:

我正在使用 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需要更新数据库中实体之间的一些边(我使用图形数据库,这意味着我的实体(通常是表中的行)是节点,它们之间的关系是边)。如前所述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. 因此,我在 中创建了一个等效方法DatabaseManagerBusinessObjectManager并将简单地调用此方法。

现在的问题是在哪里放置接口UpdatedLinks:它是需要的DatabaseManagerBusinessObjectManager并且SomeBusinessObjectManagerConsumer但是这些类(及其相应的插件)之间的依赖关系朝着这个方向发展:

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

所以:

  • 我无法UpdatedLinks放入BusinessObjectManager s 插件,因为它对于DatabaseManager.
  • 我不能把它放在DatabaseManager's 的插件中,因为那样它对于SomeBusinessObjectManagerConsumer(记住它SomeBusinessObjectManagerConsumer不知道任何关于DatabaseManager; 由于 OSGi 中的模块化,它只能访问DatabaseManager关于不想做)。
  • 把它放在某种“实用程序”插件中太具体了。
  • 我目前没有任何插件可以放置此接口,这将使所有相关插件都可以使用它。

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

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


“元”免责声明:

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

1 回答 1

1

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

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

于 2015-09-18T10:35:42.610 回答