在过去的一个问题中,我问如何设计一个系统:
- 一个类包含一个或多个可选方法。
- 可选方法由在编译时可能存在或不存在的插件实现。
- 如果用户调用一个相关插件在编译时不存在的方法,他们将得到一个编译时错误。
我提供了一种适用于 Java 8 的可能解决方案。
不幸的是,这个解决方案依赖于 Java 9 模块系统不允许的拆分包(两个模块导出同一个包)的使用。
这如何在 Java 9 中实现?
如果我正确理解了这个问题,那么您期待使用的是模块系统中的服务。
Java 长期以来一直通过
java.util.ServiceLoader
类来支持服务,该类在运行时通过搜索类路径来定位服务提供者。
模块系统可以通过扫描模块工件中的类文件以查找ServiceLoader::load
方法的调用来识别服务的使用。
使用您当前的项目结构,您应该定义一个abstract class
或一个interface
可以扩展在guava
,core
模块类中实现并由它们提供的。
一个模块使用一个特定的服务是该模块定义的一个重要方面,因此为了效率和清晰度,它在模块的声明中用一个uses
子句表示:
module com.foo.bar.sql {
uses com.foo.Verifiers;
}
模块提供特定服务的实现同样重要,但是,这在模块的声明中带有一个provides
子句:
module guava {
provides com.foo.Verifiers with com.guava. GuavaVerifier;
}
module core {
provides com.foo.CoreVerifier with com.guava. GuavaVerifier;
}