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 modules
es 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 interface
es public
- expuesto al mundo. Por lo general, lo que hago es tener algunas package-private
clases, 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-private
clases 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 HelperUsage
y FactoryUsage
lo será public
y 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.
modules
resuelve este problema de una manera hermosa: public
ya no es realmente public
; Puedo tener friend
acceso vía exports to
directiva. 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/gradle
maneje 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 jarA
y 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".