0

根据我在不同地方阅读的最佳实践(一个示例),将 API 和实现分开是理想的,但也只在 API 包中导出包而不是在实现包中导出包,而实现包应该注册为服务。

但是我仍然不清楚你应该如何扩展一个具体的类。在我看来,能够做到

class Child extends com.foo.ParentImpl {
}

impl 捆绑包需要公开com.foo

AFAIU只有两种方式

  1. 导出具体实现,但这违反了最佳实践
  2. 永远不要从不同的包中扩展类。即将所有类型层次结构捆绑在一起。在我看来,这种方式违背了模块化框架的意义

那么这样做的正确方法是什么?

4

2 回答 2

4

您可以将实现类公开为导出——OSGi 不会阻止您这样做。请注意,您违反了最佳实践。

你可能会争辩说,最佳实践注定要被打破,在某些情况下你是对的。但是,这确实是有充分理由存在的!Java 中的继承在基类和子类之间创建了非常紧密的耦合。通过允许其他捆绑软件可以看到您的实现类并可能将它们子类化,您会严重限制您在基类中进行实现更改的能力。本质上,实现API,因此将来无法更改。

所以我的建议是忘记继承。它被高估了。

如果您真的想这样做,请按照您的选项 2 将层次结构保持在一起。

于 2013-06-28T20:37:45.327 回答
2

TLDR:分离 API 和实现最好留给那些作为 OSGI 服务公开的东西,这些服务的实例将从包中引用。否则,只需按原样公开您的课程。

您在 OSGI 中获得的模块化类型并不适合扩展服务类。您最好使用一些允许您扩展服务功能的设计模式。

我还想知道您要扩展什么类以及它的目的是什么。

现在,如果您绝对必须在捆绑包之外扩展服务类,那么最好的选择可能是委托。

 class MyExtendedService implements Service {
    Service service;
    //delegate to MyService which also implements Service and
    //  is pulled from another osgi bundle.
 }

现在,如果您要定义“事物”类,例如模型或值对象,则可能没有理由拥有单独的 API 和实现类。照原样暴露它们。

于 2013-06-28T19:16:43.637 回答