【问题标题】:Method access and non exported package方法访问和非导出包
【发布时间】:2017-05-20 12:51:27
【问题描述】:

我有一个包含两个包的 OSGi 包:

  1. com.organization.api这个包被导出了。
  2. com.organization.internal这个包没有被导出。

com.organization.api我有一个接口Foo和类AsbtractFoo

package com.organization.api;

public abstract class AbstractFoo implements Foo {

   private int state;

   @Override
   public int getState(){ 
       return this.state; 
   }
}

com.organization.internal 我有一个类FooManager 需要改变Foo 的状态。在com.organization.internal之外的任何其他类都不能改变foo的状态的情况下如何做到这一点。

package com.organization.internal;

public class FooManager {

   private ???? foo = ....

   public void updateFooState(){
      foo.????();
   }
}

我尝试使用默认访问设置器 (void setState(int state)) 将 AbstractStatefullFoo 添加到包 com.organization.internal 并让 AbstractFoo 扩展 AbstractStatefullFoo 但问题是这种情况下其他捆绑包需要导出包 com.organization.internal .

这样的问题在 OSGi 中如何解决?

【问题讨论】:

    标签: java osgi


    【解决方案1】:

    我感觉您正在考虑使用所有这些抽象类进行复杂化。

    最简单的情况是有一个接口 Foo 和 getState。 然后,您在内部包中有一个 Foo 的实现。

    这种情况不需要其他捆绑软件可以访问内部的 impl 类。关键是api包里也要有FooManager的接口。

    然后创建实现 FooManager 的 FooManagerImpl 并将其导出为具有接口的服务。然后其他包可以使用此服务来调用 updateState() 方法和其他操作 FooImpl 类的方法。

    【讨论】:

    • 感谢您的回答,但我真的需要抽象类,因为它们包含很多实现,这些实现在其他包的具体类中继承。
    • 您也可以在两者之间使用抽象类。关键是使用 OSGi 服务并让其他包只使用 api 包中的类。
    【解决方案2】:

    扩展上一个答案。

    如果您封装可变的 foo 状态,并将工厂作为服务公开,那么可能会为您简化一些事情。将 foo 管理器服务作为工厂可能是明智的,以确保它们保持同步。

    FooState 实现可以提供用于更改状态的方法,这些方法不包含在接口中,并且对于实现包是私有的。 FooState 接口应标记为不适用于 Consumer 实现。

    可以更改 Foo 接口以允许访问 FooState。这个对象是只读的(除非使用反射),但不是不可变的。您可以将访问方法直接添加到 Foo,或者您可以创建一个额外的导出接口,以避免不关心此操作的 API 用户使接口复杂化。 AbstractFoo 实现可以移动到单独的导出包中。如果默认实现可能会产生受保护的方法并且通常比 API 本身更改得更快,那么这可能会很好,您不必频繁地更改 API 的版本。

    抽象类可以负责获取 FooState 以及其他实现支持任务。

    如果您需要能够在不更新 Foos 的情况下更新管理器实现,可能会有一些额外的复杂情况,但这似乎不是必需的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-08
      • 1970-01-01
      • 2018-11-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多