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

Adapters and modularization without transitive dependencies

我 运行 遇到过几次以下情况,但我找不到完全满意的解决方案:

我正在使用 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)

在哪里

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

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

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

...应该确保到 return 时,from 业务 object 只会 linked 到to objects,可能删除以前的 links 并添加新的。我想知道这些删除和添加。我在插件 com.example.core.business.objectmanager:

中创建了一个接口 UpdatedLinks
public interface UpdatedLinks {
    Set<BusinessObjectUID> getRemovedLinks();
    Set<BusinessObjectUID> getAddedLinks();
}

但是 BusinessObjectManager 并不是真正要执行此 link 替换并将 UpdatedLinks return object 放在一起的人。相反,它将此委托给 DatabaseManager。所以我在 DatabaseManager 中创建了一个等效方法,BusinessObjectManager 将简单地调用此方法。

现在的问题是接口 UpdatedLinks 的放置位置:DatabaseManagerBusinessObjectManagerSomeBusinessObjectManagerConsumer 需要它,但是这些 [=127] 之间的依赖关系=](及其相应的插件)朝这个方向发展:

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

所以:

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

我遇到过好几次这种情况(尤其是最近使用OSGi,因为模块化),我一直找不到一个完全令人满意的解决方案。 would/do遇到这种情况怎么办?


"Meta" 免责声明:

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

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