servicios - java capa de persistencia
Capa de servicio JSF (2)
No estoy seguro de si mi enfoque con el entorno MVC en JSF es la mejor manera de hacerlo. Como estoy tratando de sacar el máximo provecho de JSF, me gustaría saber cómo se debería ''diseñar'' mi capa de servicio (o modelo, hablando en términos de MVC).
Sé que la relación Ver-Controlador debe ser de 1 a 1 (excepciones excluidas). Ahora, ¿de qué manera debo diseñar mi capa de servicio? ¿Debo usar un gran servicio (no lo creo)? Si no, ¿en base a qué debería dividir mis servicios?
Tenga en cuenta que mi Servicio se llamará desde Beans (Controladores en términos de MVC) y el Servicio mismo llamará a DAO utilizando JPA cuando sea necesario.
Gracias por adelantado
La relación 1: 1 entre servicios y entidades modelo quizás no esté mal si tiene pocas entidades en su aplicación. Pero si es una gran aplicación, habría demasiados servicios.
La cantidad de servicios depende de los casos de uso de la aplicación que está diseñando. Una vez que los haya identificado en la fase de análisis, debe agruparlos en varios grupos según su funcionalidad. Cada grupo de casos de uso será un Servicio, y cada caso de uso será un método en ese servicio. Cada servicio puede administrar varias entidades modelo (y debe insertar en ella los DAO que necesita para realizar su funcionalidad). Por lo general, los casos de uso de un servicio gestionan entidades de modelo interrelacionadas en el diagrama de clases del modelo. Los Servicios pueden seguir la buena práctica de "cohesión máxima / acoplamiento mínimo".
La relación entre los DAO y las entidades modelo es de 1: 1. Cada DAO realiza operaciones CRUD y consultas de su entidad. Si un método necesita consultar 2 entidades relacionadas, colóquelo en el DAO más adecuado según los conceptos de negocio.
En la capa de presentación JSF, tampoco tengo una relación 1: 1 entre páginas y controladores, eso sería demasiados controladores. Agrupe en un colaborador todas las páginas necesarias para realizar los casos de uso de cada servicio. Entonces, la relación 1: 1 es entre controladores y servicios, inyectando cada servicio en el controlador cuyas páginas realizan sus casos de uso.
Por supuesto, estos son principios generales. Es posible que tenga algunos casos particulares en la aplicación que los rompió, pero son pocos.
Es posible que no tengas demasiados servicios y controladores, pero tampoco demasiados porque entonces tendrían demasiada lógica y campos. Debes lograr un compromiso.
La capa de servicio (el modelo de negocio) debe diseñarse alrededor de la entidad principal (el modelo de datos). Por ejemplo, UserService
para el User
, ProductService
para el Product
, OrderService
para el Order
, etc. No debe tener absolutamente una gran clase de servicio más o menos. Eso es un acoplamiento extremadamente ajustado.
En cuanto a la API de la capa de servicio, Java EE 6 ofrece EJB 3.1 como API de capa de servicio. En las oscuras edades J2EE, hace mucho tiempo cuando era terrible desarrollar EJB 2.0, Spring se usaba más a menudo como API de capa de servicio. Algunos todavía lo usan hoy en día, pero como Java EE 6 ha incorporado todas las buenas lecciones aprendidas de Spring, se ha vuelto superfluo . Tenga en cuenta que EJB (y JPA) no está disponible en servidores de servlets barebone como Tomcat. Debería instalar, por ejemplo, OpenEJB encima (o simplemente actualizar a TomEE).
Independientemente de la elección de la API de la capa de servicio, lo mejor sería mantener sus métodos de escucha de bean (acción) de respaldo de JSF lo más resbaladizos posible realizando el trabajo comercial por completo en la capa de servicio. Tenga en cuenta que la capa de servicio no debería tener ninguna dependencia JSF. Por lo tanto, cualquier importación (in) directa de javax.faces.*
En el código de capa de servicio indica un diseño incorrecto. Debe mantener las líneas de código particulares en el bean de respaldo (generalmente es un código que agrega un mensaje de rostros dependiendo del resultado de la llamada de servicio). De esta forma, la capa de servicio es reutilizable para otras interfaces, como JAX-RS o incluso servlets normales.
Debe comprender que la principal ventaja de la capa de servicio en una aplicación Java EE es la disponibilidad de transacciones gestionadas por contenedor. Una llamada a un método de servicio en un @Stateless
EJB cuenta efectivamente como una única transacción de base de datos. Por lo tanto, si se produce una excepción durante una de las operaciones DAO utilizando @PersistenceContext EntityManager
invocado por la llamada al método de servicio, se desencadenará una reversión completa . De esta forma se termina con un estado de base de datos limpio en lugar de un estado de base de datos sucio porque, por ejemplo, la primera consulta de manipulación de base de datos se realizó correctamente, pero la segunda no.