Solo puedo decirles la opinión de mi organización al respecto. Nos encontramos en el proceso de mover a los módulos, para cada proyecto que estamos trabajando. Lo que estamos construyendo son básicamente microservicios + algunas bibliotecas cliente. Para los microservicios, la transición a moduleses de alguna manera una prioridad menor: el código ya está aislado de alguna manera en el contenedor de la ventana acoplable, por lo que "agregar" módulos allí no parece (para nosotros) muy importante. Este trabajo se está recuperando lentamente, pero es de baja prioridad.
Por otro lado, las bibliotecas cliente es una historia completamente diferente. No puedo decirte el lío que tenemos a veces. Explicaré un punto que odié antes jigsaw. Expone una interfaz a los clientes, para que todos la utilicen. Automáticamente eso interfacees public- expuesto al mundo. Por lo general, lo que hago es tener algunas package-privateclases, que no están expuestas a los clientes, que usan esa interfaz. No quiero que los clientes usen eso, es interno. ¿Suena bien? Incorrecto.
El primer problema es que cuando esas package-privateclases crecen y quieres más clases, la única forma de mantener todo oculto es crear clases en el mismo paquete:
package abc:
-- Usage.java
-- HelperUsage.java
-- FactoryUsage.java
....
Cuando crece (en nuestros casos lo hace), esos paquetes son demasiado grandes. ¿Te mudas a un paquete separado que dices? Claro, pero eso HelperUsagey FactoryUsagelo será publicy tratamos de evitarlo desde el principio.
Problema número dos: cualquier usuario / llamador de nuestros clientes puede crear el mismo nombre de paquete y extender esas clases ocultas. Ya nos pasó algunas veces, momentos divertidos.
modulesresuelve este problema de una manera hermosa: publicya no es realmente public ; Puedo tener friendacceso vía exports todirectiva. Esto facilita mucho la gestión y el ciclo de vida de nuestro código. Y nos alejamos del infierno de classpath. Por supuesto, maven/gradlemaneje eso por nosotros, principalmente, pero cuando hay un problema, el dolor será muy real. También podría haber muchos otros ejemplos.
Dicho esto, la transición (todavía) no es fácil. En primer lugar, todos los miembros del equipo deben estar alineados; segundo, hay obstáculos. Los dos más importantes que todavía veo son: ¿cómo se separa cada módulo, en función de qué, específicamente? Todavía no tengo una respuesta definitiva. La segunda es split-packages, oh, lo hermoso "la misma clase es exportada por diferentes módulos". Si esto sucede con sus bibliotecas, hay formas de mitigarlo; pero si se trata de bibliotecas externas ... no es tan fácil.
Si depende de jarAy jarB(módulos separados), pero ambos exportan abc.def.Util, se encontrará con una sorpresa. Sin embargo, hay formas de resolver esto. De alguna manera doloroso, pero con solución.
En general, desde que migramos a módulos (y todavía lo hacemos), nuestro código se ha vuelto mucho más limpio. Y si su empresa es una empresa de "código primero", esto es importante. Por otro lado, he estado involucrado en empresas en las que los arquitectos senior consideraban que esto era "demasiado caro", "ningún beneficio real".