On some of my projects, I use the double dispatch mechanism to provide at run time a "view" of my infrastructure module to my domain module (Strengthening your domain: The double dispatch pattern). What I call 'modules' above is simply separate jar files where the dependency from service.jar->domain.jar is enforced at compile time only. Will I be able to have this working on java-9 if I define my service and domain as 'true' java 9 modules?
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)
Yes that is possible. Here are some things to consider:
Fee
. Possibly to everyone but at least to service.BalanceCalculatorImpl
has to access BalanceCalculator
since it implements it.BalanceCalculatorImpl
and pass it to Fee
, this can not happen in domain or it would create a cyclic dependency.BalanceCalculator
, even inside domain, can get hold of all its implementations.Taking all of these into account, this is what the two module declarations might look like:
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;
}
Then every module that likes to use BalanceCalculator
can declare it in its module declaration with uses com.example.domain.balance.BalanceCalculator
and get instances of that using Java's ServiceLoader
.
You can find more practical applications of the module system (particularly for services] in a demo I created.
(Note: The answer was revised after this exchange.)