2014-10-01 114 views
4

有什么选项可以用Java定义到Java库的公共接口。用Java定义公共库接口

例如,我经常发现事情是公开的,因为库中的另一个包需要它们(虽然仍有一个公共基础包,例如com.stackoverflow.mylib),所以它们不能具有包访问级别,并且通常人们并不想要大量的包(这似乎是人们使用Spring坚持要有单独的controller/service/model/impl/etc包,导致一个单独的“特性”被迫跨越很多包,当说一个给定的服务可能是一个完全内部的实现细节而不是外部使用......)。

因此,理想的目标是让我向第三方提供的Jar清楚地说明这些东西是不会被使用的,理想情况下根本没有它们可用(不存在于API jar中),这样他们不可能使用和编译这些内部对象/方法。

对于那些只能从某种工厂(例如提供的Spring Bean)中获得的对象来说,更为理想的方法是防止直接从它们的代码或自定义bean实例化(这可能会留下一些未来的,尚不存在的属性升级后未初始化)。

我知道目前两家正规方法是:

  • 在一些项目中我曾上,有一个API包(如com.stackoverflow.mylib.api),而规则是只这个包的内容可以由外部用户直接访问。
  • 在我工作过的其他一些项目中,有一些自定义属性,例如@PublicSDK标记公共对象和方法(我认为一些额外的东西,以确保只标记的东西在公开分发的javadoc和api jar)。
+1

发表评论或做/建议编辑不只是近距离投票......我想知道什么技术选项(即列出任何相关的专业人士的意见)为给定的情况(图书馆代码)。 – 2014-10-01 23:06:27

回答

1

首先要问自己的是 - 你真的需要隐藏实现细节吗

我这样说的原因是,这样做会涉及费用,这取决于您的情况可能或不值得支付。

例如,如果您的API正在由您的直属团队以外的开发人员使用,那么这可能是值得的;然而,如果仅仅是隐藏你的团队中的实现细节,我认为这是过度的。

如果API用于您的项目中,那么您试图仅依赖于抽象类型或接口的标准是足够的(并且已经是标准)。

但是,假设您确实需要隐藏实现并只公开API,那么我所知道的最好方法是生成两个jar包 - 一个包含公共API,另一个包含该API的实现。

如果您使用Maven或Gradle构建使用API​​的项目,只需声明API jar(工件)的编译时依赖关系和实现jar(工件)上的运行时依赖项。

这个模式可以在整个常见Java API中看到,最新的例子是作为Glassfish的一部分单独实现的JSON API

+0

根据我的经验是,对于常见模块去其他几个团队(或公众),并且一般人们编码到IDE所说的,它有一个文档(他们可能没有真正阅读)并将其显示为公共(所以没有编译警告/错误)。然后,他们拒绝/没有资源来改变它,所以卡住支持这种内部事物的行为(因为该jar需要向后兼容很大程度,以防止在客户服务器上的困难升级情况)... – 2014-10-01 09:56:34

+0

那么,如何两罐产生?这听起来很像我的第二种方法(使用属性从API jar中删除东西) – 2014-10-01 09:58:24

+0

简单的两个项目 - 一个生成公共API,另一个生成实现。如果您使用的是Maven,那么避免使用多模块pom的诱惑 - 您将锁定自己随每次发布的实现一起释放公共API,这在尝试执行仅错误修复的bug修复版本时非常痛苦实施 – 2014-10-01 10:02:05