Assume we have a single large JVM project (the example is in Kotlin), containing code. As part of a refactoring effort, we are decoupling pieces of the code by splitting the code into multiple modules, and using a build tool such as Gradle/Maven to build deploy applications with only a small set of the modules.
Some more details:
class SomeService( private val SomeCallable: callable, // implemented by OtherService during runtime ) { fun doSomething() { callable.call() } } interface SomeCallable { fun call() } class OtherService: SomeCallable { fun call() {} }
We want to split this code into two modules:
// Module A class SomeService( private val OtherService: callable, ) { fun doSomething() { callable.call() } } // Module B class OtherService: SomeCallable { fun call() {} } // Module ??? interface SomeCallable { fun call() }
The question is in which module the interface belongs. If it would be part of module A, then the implementation in module B cannot compile. If it would be part of module B, then the calling service cannot compile. It seems we need a third module C containing just the interface SomeCallable
, and that both modules A and B depend on.
A compilation dependency diagram:
A B \ / C
A runtime dependency diagram:
A | \ B | | / C
Is this the best way to achieve the decoupling of code/modules, or are there better ways?