2010-04-14 14 views
11

Digamos que he decidido ir con Java EE stack para mi aplicación empresarial.¿Cómo modelar en Java EE?

Ahora, para el modelado de dominio (o: para diseñar el M de MVC), ¿qué API puedo suponer y usar con seguridad, y de las que debo permanecer lejos ... digamos, a través de una capa de abstracción?

Por ejemplo,

  1. ¿Debo seguir adelante y arena para mi modelo con llamadas a Hibernate/JPA API? O bien, ¿debería crear una abstracción ... una capa de persistencia propia para evitar una codificación dura contra estas dos API de persistencia específica? Por qué le pregunto esto: Hace pocos años, existía esta API de Kodo que Hibernate reemplazó. Si uno hubiera diseñado una capa de persistencia y codificado el resto del modelo contra esta capa (en lugar de ensuciar el Modelo con llamadas a una API de proveedor específica), le habría permitido cambiar (relativamente) fácilmente de Kodo a Hibernar a xyz.

  2. ¿Se recomienda hacer un uso agresivo del * QL proporcionado por su proveedor de persistencia en su modelo de dominio? No conozco ningún problema del mundo real (como el rendimiento, la escalabilidad, la portabilidad, etc.) que surja de un uso intensivo de un lenguaje similar a HQL. Por qué pregunto esto: Me gustaría evitar, en la medida de lo posible, escribir código personalizado cuando lo mismo se puede lograr a través del lenguaje de consulta que es más portátil que SQL.

Lo siento, pero soy un novato en esta área. ¿Dónde podría encontrar más información sobre este tema?

Respuesta

8

Esto es lo que creo que es el punto de vista tradicional:

  • Las entidades en su proyecto forman el modelo de dominio. Deben ser reutilizables y no estar estrechamente conectados a una tecnología de persistencia (volveré más adelante sobre el acoplamiento apretado vs. libre)
  • La capa de negocios, usa el modelo de dominio, pero también expone servicios y otras cosas.
  • La capa de acceso a datos se encarga de mantener el modelo de dominio (entidades) en una tienda persistente.

Una entidad no debe llamar a la capa de acceso a datos directamente. Pero la capa de negocios, de alguna manera, cargará y persistirá entidades del modelo de dominio.

Si asigna a que las tecnologías Java EE que se suele sentir algo como:

  • Entidades -> POJO con anotaciones de Hibernate/JPA. Tenga en cuenta que las anotaciones no implican un acoplamiento estrecho con JPA/Hibernate, el mismo POJO podría usarse en otro lugar sin Hibernate.
  • capa de negocios -> EJB de sesión o primavera
  • capa de acceso de datos -> JPA/Hibernate

Eso es un esbozo y hay una gran cantidad de variantes posibles. En particular, puede omitir el EJB de sesión e implementar la capa empresarial de otra manera. También puede decidir que la capa empresarial llame directamente a la sesión JPA/Hibernate/EntityManager, en cuyo caso JPA/Hibernate es realmente el DAL, o puede desear ajustar el acceso a Session/EntityManager en los llamados Objetos de acceso a datos (DAO)

En cuanto a HQL, trate de atenerse a lo que es portátil, y si utiliza SQL nativo, siga las convenciones de SQL-92. Si las cosas se complican, tal vez introduzca DAO. De esta forma, usted sabe que el único lugar donde hay consultas HQL es en los DAO. También puede implementar primero la lógica de consulta "procedurally" en el DAO, y si tiene un problema de rendimiento, vuelva a implementarlo con una consulta HQL más complicada.

EDITAR

En cuanto a sus preguntas en el comentario:

La capa de negocio depende de la capa de datos. Si desea que la capa empresarial no dependa de Hibernate/JPA, entonces su capa de datos necesita abstract Hibernate/JPA de distancia. Si usa DAO para su capa de datos, ese será el caso. El DAO será la "fina capa de persistencia escrita a mano sobre Hibernate" (para tomar sus palabras). Presentaría DAO para todas las entidades en su caso.

Lo que estás preguntando es una pregunta de diseño bastante genérica. No puedo dar una receta definitiva para eso, ni tampoco puedo resumir todas las variantes en una respuesta, ya que depende de cada caso. Por ejemplo, no hablamos tanto sobre el problema de las transacciones, que normalmente comienza en la capa de negocios, pero que la capa de datos debe tener en cuenta. Esto generalmente depende de las tecnologías utilizadas y sus requisitos.

Sin embargo, aquí hay una lista de los recursos que le pueden interesar: los libros Pattern of Enterprise Application Architecture, el libro Real World Java EE Patterns - Rethinking Best Practices, el libro Domain Driven Design y más específicamente los patrones Data Access Object, Repository pattern, Open Session in View (si es para una aplicación web), y tal vez Anemic Domain Model.

EDIT 2

Ok, un poco más frases sobre transacciones:

Transacciones conceptualmente deben gestionarse de la capa de negocio; la definición de lo que debe hacerse en una unidad de trabajo para ser coherente depende, de hecho, de la propia lógica de la aplicación.

Con EJB3, las transacciones se pueden declarar con anotaciones y la aplicación. el servidor lo hace por ti. Ver this other answer mío para más información. Con Spring también puede marcar las transacciones de forma declarativa, pero no sé los detalles. De lo contrario, tendrá que iniciar/detener la transacción usted mismo.Esto será ligeramente diferente si usa transacciones JDBC o transacciones JTA.

Las transacciones también se relacionan con la carga diferida en Hibernate/JPA. Una entidad que se cargó de forma diferida, de hecho, solo se puede cargar si hay una transacción actual. Si las transacciones finalizan en la capa empresarial, las entidades que se devuelven a la capa de presentación deben cargarse con entusiasmo.

Para evitar este problema, un patrón popular para aplicaciones web es Open Session in View, que ya he mencionado. En este caso, la capa de presentación inicia/detiene las transacciones (lo cual es un poco erróneo conceptualmente), pero funciona bien con la carga diferida.

+2

Estoy totalmente de acuerdo, y eventualmente recomendaría usar JPQL en lugar de HQL para cumplir con los estándares. – snowflake

+0

Puedo estar equivocado sobre la terminología aquí. Cuando dije 'modelado de dominio', me refería a la tríada M de MVC, que en esencia es la 'aplicación central' (incluida la capa empresarial), algo que potencialmente podría conducir a través de una interfaz de línea de comando (reescribiendo la V y la C para la CLI)! Ahora, una de las cosas que hará esta M es la persistencia. Para esto, la M necesita estar libre de cualquier cosa de persistencia específica del proveedor. Por lo tanto, la necesidad de una fina (o, gruesa/sofisticada) capa de persistencia escrita a mano sobre Hibernate. ¿Podrías corregirme si me equivoco aquí? – Harry

+0

"Si las cosas se complican, tal vez introduzca DAO". Quiere decir, caso por caso (suponiendo, por supuesto, que DAO y HQL/JPQL coexistan pacíficamente). Realmente me gustaría poder diseñar mis objetos de tal manera que HQL sea suficiente (debido al poder del paradigma relacional), y para consultas realmente complicadas, escribo código imperativo. – Harry

4

Su modelo de dominio y su capa de persistencia deberían estar separados en teoría; no es necesario que una clase llamada Entity sepa nada sobre cómo y cómo persiste, por lo que podría usar algo como Hibernate para crear la capa de persistencia sin contaminar las clases del modelo de dominio en sí. No "codifica el modelo [...] contra esta capa": codifica el modelo y luego lo asigna a una tienda persistente con algún tipo de capa ORM, donde el modelo de dominio no depende de la capa ORM. Obviamente, la capa de persistencia dependerá del modelo de dominio, pero está bien.

Personalmente lucho por usar demasiado HQL con (N) Hibernate por la razón que usted pregunta, pero hay momentos en los que es inevitable. Usted ya sabe, y usted mismo ha resaltado, el problema principal allí, por lo que es poco probable que lo use en exceso de todos modos.

+0

"luego asignarlo a una tienda persistente con algún tipo de capa ORM": Sí, solo quise decir eso. Parece que lo que estás diciendo es: construir una capa encima de Hibernate en lugar de ensuciar el modelo llamado con llamadas directas a Hibernate API, ¿verdad? – Harry

+1

Cerca, pero no del todo, estoy diciendo construir un modelo, y luego aplomarlo a la capa de persistencia. Cuando está codificando las clases de su modelo de dominio, no le importa cómo o incluso si van a una base de datos. Ciertamente no deberías sentir que estás construyendo esas clases "encima de Hibernate". –