2010-05-29 55 views
7

我很努力的为大众消费打包一个API。正因如此,我试图限制那些只希望公开并支持的方法。当然,在这之下有许多有限的访问方法。我的内部API类应该全部在一个包中吗?

问题是,我有很多内部代码需要访问这些受限制的方法而不公开这些方法。这就造成了两个问题:

  • 到 类之间的沟通,因为这 会使我的这些内部方法 公共我不能创建接口。
  • 我无法访问受保护或默认的 方法,除非我将大部分 我的内部类放在同一个 包中。

所以,我有大约70或80个内部类在干净分离的包,但有过分宽容的访问修饰符。你会说单一包装是两种邪恶中较小的一种,还是有更好的方法能够掩盖我的内部方法,同时保留更多的粒状包装?

我很想知道这里的最佳做法。

我已经知道This

+0

我认为这个问题有点主观:我个人不喜欢导致内部组织糟糕的设计决策,比如你的全班合一包装案例。但是做这种事情的正确方式现在还没有想到。 – incarnate 2010-05-29 07:36:41

回答

7

对于您的问题有两种解决方案,不涉及将所有类保留在同一个包中。

第一种是使用(Practical API Design,Tulach 2008)中描述的Friend Accessor/Friend Package模式。

第二个是使用OSGi。有一篇文章here解释OSGi如何完成这一点。

相关问题:12,34

+0

这是一个很好的答案,链接到朋友包只是我正在寻找的解决方案。 – Chris 2011-05-28 06:11:27

+0

我很高兴能帮到你。我也需要一个解决这个看似严重的Java限制。这种模式应该是使用Jetbrains MPS或其他模型驱动的开发工具来扩展J​​ava的理想候选者。 – 2011-05-28 16:09:35

+0

那么,你仍然必须公开内部抽象Accessor(因此是API的一部分)。 更糟的是,恶意用户可以提供他/她自己的AccessorImpl,从而迫使您的内部软件包使用他/她自己的API。这将工作,直到Item类被初始化并触发IllegalStateException。 – charlie 2012-10-18 13:55:13

2

一个例子可能是Servlet API正如你看到的,他们已经分居了共同的servlet API和HTTP成两个包。

如果您将代码分开放在api.jarimplementation.jar之间,那么您可以使用api.jar用户不可见的实现接口。 如果类的对象不考虑它们的包,必须以任何方式协作,当然这些方法必须是可见的(至少在实现中)。

+0

+1感谢您的信息。我知道我可以将这个问题封装起来,但是我真的希望限制那些同时具有api和实现jar的用户无法以非预期的方式访问非接口实现方法。 – Chris 2011-05-28 06:14:06

1

是的,你只是不能保护内部实现的东西访问。有一些技术(如OSGi)可以在运行时/应用程序启动时提供解决方案。这是一种java语言设计模块化缺陷(但由于向下兼容性,此后也很难添加)。

我喜欢将公开可见工件添加到/api包和内部到/内部的约定。最后,你最终结束了。

 

# this package is allowed to be accessed by api-users 
com.foo.users.api 
# this is completely internal logic (api implementation) 
# should only be touched by the api-module itself. 
com.foo.users.internal 
 

这样你就有了干净的分隔,并且还可以运行静态代码分析代码规则。

与上面提到的servlet-api一样,您甚至可以将api和impl进一步拆分为不同的jar。但是这需要更多的努力来构建生命周期和维护模块,所以我只会在完整的运行时工件拆分有意义的地方(比如在jsr-spec和impl中)做到这一点。

相关问题