java spring java-ee package-design

java - ¿El enfoque paquete por característica es bueno?



spring java-ee (3)

Eche un vistazo a los Principios de diseño de paquetes del tío Bob. Explica las razones y las motivaciones detrás de esos principios, que he detallado a continuación:

Las clases que se reutilizan juntas deben empaquetarse juntas para que el paquete se pueda tratar como una especie de producto completo disponible para usted. Y aquellos que se reutilizan juntos deben separarse de aquellos con los que no se reutilizan. Por ejemplo, sus clases de utilidad de registro no se usan necesariamente junto con sus clases de archivo io. Así que empaquete todo registrándolos por separado. Pero las clases de registro podrían estar relacionadas entre sí. Por lo tanto, cree un tipo de producto completo para registrar, por ejemplo, para la necesidad de un mejor nombre commons-logging, empaquételo en un jar (reutilizable) y otro producto completo separado para utilidades io, nuevamente para la falta de un mejor nombre, digamos commons- io.jar. Si actualiza la biblioteca say commons-io para decir que es compatible con java nio, es posible que no desee necesariamente realizar ningún cambio en la biblioteca de registro. Entonces, separarlos es mejor.

Ahora, digamos que quería que sus clases de utilidad de registro admitan el registro estructurado para decir algún tipo de análisis de registro por herramientas como splunk. Es posible que algunos clientes de su herramienta de registro quieran actualizar a su versión más nueva; algunos otros pueden no. Entonces, cuando publique una nueva versión, empaquete todas las clases que sean necesarias y reutilizadas juntas para la migración. Por lo tanto, algunos clientes de sus clases de utilidad pueden eliminar de forma segura su antiguo contenedor de registro de recursos comunes y pasar a commons-logging-new jar. Algunos otros clientes todavía están bien con el jar más antiguo. Sin embargo, no se necesitan clientes para tener estos dos jarrones (nuevos y viejos) solo porque los obligó a usar algunas clases para el jar empaquetado anterior.

Evite las dependencias cíclicas. a depender de b; b en c; c en d; pero d depende de a. El escenario es obviamente disuasivo, ya que será muy difícil definir capas o módulos, etc. y no se puede variar de forma independiente entre sí.

Además, podría empaquetar sus clases de modo que si una capa o módulo cambia, otros módulos o capas no tengan que cambiar necesariamente. Entonces, por ejemplo, si decide pasar de una antigua estructura de MVC a una actualización de API de descanso, entonces solo la vista y el controlador pueden necesitar cambios; tu modelo no.

Recientemente me encontré con esta publicación javalobby http://java.dzone.com/articles/how-changing-java-package en el código de embalaje de Java por función.

Me gusta la idea, pero tengo pocas preguntas sobre este enfoque. Hice mi pregunta pero no obtuve una respuesta satisfactoria. Espero que alguien en StackOverflow pueda aclarar mis preguntas.

Me gusta la idea de paquete por característica que reduce enormemente el tiempo para mover los paquetes mientras se codifica y todo lo relacionado estará en un lugar (paquete). Pero, ¿qué ocurre con las interacciones entre los servicios en diferentes paquetes?

Supongamos que estamos creando una aplicación de blog y estamos colocando todas las operaciones relacionadas con el usuario (controladores / servicios / repositorios) en el paquete com.mycompany.myblog.users . Y todas las operaciones relacionadas con publicaciones de blog (controladores / servicios / repositorios) en el paquete com.mycompany.myblog.posts .

Ahora quiero mostrar el Perfil de usuario junto con todas las publicaciones que publicó. ¿Debo llamar myblog.posts.PostsService.getPostsByUser(userId) de myblog.users.UserController.showUserProfile() ?

¿Qué pasa con el acoplamiento entre paquetes?

También cada vez que leo sobre el paquete por característica, todos dicen que es una buena práctica. Entonces, ¿por qué muchos autores de libros e incluso marcos animan a agrupar por capas? Solo curiosidad por saber :-)


Hay muchos otros aspectos además del acoplamiento para el diseño de paquetes que sugeriría mirar los Préstamos OOAD, especialmente los principios de diseño de paquetes como

REP El Principio de Equivalencia de Reutilización de Liberación El gránulo de reutilización es el gránulo de liberación.

CCP El principio de cierre común Las clases que cambian juntas se empaquetan juntas.

CRP El principio de reutilización común Las clases que se usan juntas se empaquetan juntas.

ADP El Principio de Dependencias Acíclicas El gráfico de dependencia de los paquetes no debe tener ciclos.

SDP El principio de dependencia estable depende de la estabilidad.

SAP El principio de abstracciones estables La abstracción aumenta con la estabilidad.

Para obtener más información, puede leer el book "Desarrollo de software ágil, principios, patrones y prácticas"


Personalmente, me gusta el enfoque "paquete por función", aunque es necesario aplicar bastante juicio sobre dónde dibujar los límites del paquete. Sin duda es un enfoque factible y sensato en muchas circunstancias.

Probablemente debería lograr el acoplamiento entre paquetes y módulos usando interfaces públicas, esto mantiene el acoplamiento limpio y manejable.

Está perfectamente bien que el paquete "publicaciones de blog" llame al paquete de "usuarios" siempre que utilice interfaces públicas bien diseñadas para hacerlo.

Sin embargo, un gran consejo si se analiza este enfoque: tenga muy en cuenta sus dependencias y, en particular, evite las dependencias circulares entre paquetes. Un buen diseño debe parecerse a un árbol de dependencias, con áreas de funcionalidad de nivel superior que dependen de un conjunto de servicios comunes que dependen de bibliotecas de funciones de utilidad, etc. En cierta medida, esto comenzará a parecerse a "capas" arquitectónicas con frente paquetes finales que llaman a servicios de back-end.