Java 9 模块和 DDD 中的双重调度

Java 9 module and double dispatch in DDD

在我的一些项目中,我使用双分派机制在 运行 时间向我的域模块 (Strengthening your domain: The double dispatch pattern) 提供基础结构模块的 "view"。我上面所说的 'modules' 只是单独的 jar 文件,其中来自 service.jar->domain.jar 的依赖性仅在编译时强制执行。如果我将我的服务和域定义为 'true' 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)

是的,这是可能的。以下是一些需要考虑的事项:

  1. 模块 domain 需要 export the package containing Fee. Possibly to everyone but at least to service.
  2. 模块 service 必须 require domain as BalanceCalculatorImpl has to access BalanceCalculator 因为它实现了它。
  3. 看来 service 的客户也需要了解 domain,这是 implied readability 的教科书案例.
  4. 在简单的设置中,service 或某些第三方模块必须实例化 BalanceCalculatorImpl 并将其传递给 Fee,这不会发生在 domain 否则会产生循环依赖。
  5. 一个更高级的解决方案是 services,其中所有可以访问 BalanceCalculator 的代码,甚至在 中,都可以获取其所有实现.

考虑到所有这些,这就是两个 module declarations 的样子:

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's ServiceLoader.

获取它的实例

您可以在 a demo I created.

中找到更多模块系统的实际应用(特别是服务)

(注:答案是在之后修改的。)