2

在我的一些项目中,我使用双分派机制在运行时向我的域模块提供我的基础结构模块的“视图”(加强您的域:双分派模式)。我在上面所说的“模块”只是单独的 jar 文件,其中来自 service.jar->domain.jar 的依赖项仅在编译时强制执行。如果我将我的服务和域定义为“真正的”java 9 模块,我是否能够在 java-9 上使用它?

module domain
  L Fee.java
      L Payment recordPayment(double, BalanceCalculator)
  L BalanceCalculator.java
module service
  L BalanceCalculatorImpl.java // implements BalanceCalculator
      L double calculate(Fee fee) //call fee.recordPayment(amount,this)
4

1 回答 1

3

是的,这是可能的。这里有一些要考虑的事情:

  1. 模块需要导出包含Fee. 可能对所有人,但至少服务
  2. 模块服务必须要求,因为BalanceCalculatorImpl它实现了它 BalanceCalculator
  3. 看起来服务的客户也需要了解,这是隐含可读性的教科书案例。
  4. 在简单的设置中,服务或某些第三个模块必须实例化BalanceCalculatorImpl并将其传递给Fee,这不能在域中发生,否则会产生循环依赖。
  5. 更高级的解决方案是services,所有可以访问的代码BalanceCalculator,甚至是在domain内部,都可以获取它的所有实现。

考虑到所有这些,这就是两个模块声明的样子:

module com.example.domain {
    // likely some requires clauses

    // export packages containing Fee and BalanceCalculator
    exports com.example.domain.fee;
    exports com.example.domain.balance;
}

module com.example.service {
    requires public com.example.domain;
    // likely some more requires clauses

    // expose BalanceCalculatorImpl as a service,
    // which makes it unnecessary to export the containing package
    provides com.example.domain.balance.BalanceCalculator
        with com.example.service.balance.BalanceCalculatorImpl;
}

然后每个喜欢使用的模块BalanceCalculator都可以在其模块声明中声明它,uses com.example.domain.balance.BalanceCalculator并使用Java 的ServiceLoader.

您可以在我创建的演示中找到模块系统的更多实际应用(尤其是服务)。

(注:本次交流后对答案进行了修改。)

于 2016-09-30T06:37:36.337 回答