2010-01-19 6 views
8

¿Cuál es el mejor enfoque que se debe tomar cuando se extraen objetos modelo de múltiples fuentes de datos?¿Existen patrones para las clases de modelo/entidad

Por ejemplo, tengo una aplicación que tiene algunos datos almacenados en una base de datos mySQL utilizando hibernate. ¿Qué sucede si quiero almacenar algunos otros objetos en EC2 o Google App Engine? Entiendo que DAO resume la implementación del trabajo con una fuente de datos en particular, pero ¿qué ocurre con las entidades mismas?

Al principio pensé que anotar mis entidades con anotaciones jpa fue una gran solución, pero ahora parece que realmente he vinculado mis entidades a una implementación particular. En el caso de App Engine, por ejemplo, algunas de estas anotaciones no tienen sentido.

Parece que necesito una clase POJO pura para representar mis entidades, completamente libre de lógica de persistencia. Si quería modelar un perro, por ejemplo (sí, elección coja, pero lo que sea).
¿Tendría sentido tener una clase de perro abstracta, luego definir subclases para trabajar con soluciones de persistencia particulares: HibernateDog, GAEDog, etc.

Thanks.

Respuesta

4

Esta es una gran pregunta, incluso si el problema no es nuevo. Como industria, hemos cambiado la "sabiduría convencional" sobre este tema con frecuencia a lo largo de los años. Las respuestas que obtiene hoy no son necesariamente lo que obtendría hace 5 años o 5 años en el futuro.

Al imaginar cómo Me gustaría me gusta manejar este artículo, me pregunto acerca de algunas cosas que no ha dicho: ¿es su aplicación el "sistema de registro" para las entidades de perros? Qué otros subsistemas/capas/aplicaciones necesitan saber sobre las entidades Dog.

En Java, cuando escribes nuevos tipos como Animal> Perro, obtienes la siguiente recompensa: la oportunidad de escribir un montón más código que sepa cómo interactuar con objetos animales y objetos de perro. Estoy menos convencido en 2010 de que esta es una buena idea que hace cinco años.

¿Es usted responsable de diseñar la base de datos donde se almacena la información del perro? Solíamos hacer eso todo el tiempo, pero hoy en día generalmente me encuentro integrando con registros de datos que en realidad son administrados por otros sistemas: APIs de Google, entidades LDAP, data warehouses, productos como Peopleoft, etc.

Si usted es no encargado de definir qué es un perro y cómo interactúan con el universo, consideraría una forma independiente del dominio para modelar la información del perro en la memoria. Hay toneladas: XML/DOM, JSON, mapa, etc.

Las ventajas de mover datos de otras personas en torno a estos formatos son muchos ...

  • que no tienen que escribir POJOs
  • estos son ricos en características, la documentación y las pruebas
  • hay numerosas API existentes para transformar, manipular y serializar estas criaturas
  • que podría obtener de reutilizar la vista/controlador/otro código a través de otros dominios

Por otro lado ... si usted es el sistema de registro de datos de perros, considere el uso de interfaces en lugar de clases abstractas. O quizás interfaces y clases abstractas. Java solo tiene herencia única; Ate su vista/controlador/otro código a las interfaces para garantizar la flexibilidad más futura.

2

Uno de los problemas con Hibernate es que inyecta sus propias implementaciones Collection en su clase de dominio, causando problemas si intenta enviar su clase por cable mediante serialización (por ejemplo, de servidor a cliente).

En el ejemplo anterior me pondría en duda la necesidad de proporcionar específicos del almacenamiento subclases:

Do/debería contener las clases realmente Estado perteneciente a la forma en que fueron almacenados? es decir, ¿es este un concepto central para la clase y, por lo tanto, merece la pena utilizar su "única oportunidad" en la herencia (en Java, eso es)? Yo diría que una jerarquía de herencia más útil en su ejemplo sería algo así como:

  • Animal
    • de Mamíferos
      • perro
      • gato

Además, con el diseño que propone puede tener problemas si, por ejemplo, desea guardar una instancia de Dog en Hibernate, pero no sabe si Dog es HibernateDog, GAEDog, etc. y debe realizar comprobaciones/downcasting en este punto.

1

Lo que parece ser la forma correcta. Un buen diseño no significa que las entidades no estén atadas a una tecnología, solo significa que si cambia la tecnología solo cambie 1 capa de su aplicación.

Las entidades con JPA son una buena solución si está utilizando JPA. Además de esas entidades, puede tener más "entidades" (POJO) conectadas a GAE, etc.

Acerca del perro y las subclases abstractos, parece una exageración, excepto si realmente lo necesita.Si realmente lo necesita, compruebe los objetos DTO: http://en.wikipedia.org/wiki/Data_transfer_object

DTO se utilizan para transferir el objeto a capas superiores (por encima de DAO) de forma coherente (y hacerlo serializable) incluso cuando se trata de múltiples fuentes de datos/tecnologías en el capa de persistencia

2

Las anotaciones JPA pueden ser agradables porque le permiten colocar sus metadatos de mapeo relacional de objetos (ORM) en los mismos archivos que las clases de entidad, pero tiene toda la razón de que hay una mezcla de preocupaciones cuando combina JPA metadatos con POJOs "puros". Es una compensación.

Hay una alternativa, sin embargo. Puede externalizar la configuración ORM en archivos XML y de esa manera mantener esos detalles fuera de las clases de entidad. JPA proporciona una sintaxis de configuración XML, pero para mis proyectos, prefiero usar asignaciones nativas de Hibernate XML para la flexibilidad adicional que proporcionan. Puede que no esté tan de moda como un enfoque basado en anotaciones, pero en mi experiencia, funciona bastante bien.

2

Tiene razón al usar una capa DAO para abstraer los detalles de la fuente de datos de otras capas. Por lo tanto, la capa de modelo en realidad no debería tener conocimiento de qué técnica de almacenamiento de datos o qué base de datos se está utilizando.

La respuesta a su pregunta será: Usar capa de servicio. Esta es la capa donde pones todo tu código comercial. Qué entidad instanciar, qué DAO usar, cómo corroborar datos, demarcación de transacción, etc.

Por lo tanto, la capa de servicio debe cargar o persistir en sus entidades. Y ahí es donde debe incorporar la lógica sobre qué fuente de datos/base de datos usar. Use la inyección de dependencia de Spring para ayudarlo con eso. Inyecte su elección de los DAO, Entidades en la capa de Servicio.

clases Institución: perro, gato

clases de servicio: AnimalCenterService

clases DAO: AnimalCenterHibernate, AnimalCenterJDBC

Quiero saber si se necesita más explicación. Solo mis 2 centavos

1

No querrá que su código específico de persistencia herede de sus clases de entidad, ya que eso imposibilitaría el uso de la herencia para las clases de entidad de su dominio. Por ejemplo, si tiene HibernateDog heredado de Dog, no se le permitirá tener Poodle heredado de Dog sin forzar a Poodle a ser específico de Hibernate.

Un enfoque que funciona es el uso de entidades de datos que son específicas de la persistencia. Sus clases de entidad de dominio delegarían en el objeto de entidad de datos sus atributos persistentes a través de una interfaz. A continuación, puede sustituir clases de entidad de datos específicas de implementación de persistencia diferentes siempre que se ajusten a la interfaz de entidad de datos.

Referencias de perros (y delega en la interfaz DogEntity). Poodle hereda de Dog, PoodleEntity hereda de DogEntity.

HibernateDog implementa DogEntity
HibernatePoodle implementa PoodleEntity y hereda de HibernateDog.
...
StubDog implementa DogEntity
StubPoodle implementa PoodleEntity y hereda de StubDog
...

Puede tener tantos tipos de entidades de datos como desee. Las entidades de datos serían muy delgadas y solo contendrían las variables de miembros persistentes y las anotaciones o cualquier otro código que sea necesario para la persistencia.

Las entidades de dominio contendrían la lógica empresarial específica de la entidad.

Cuestiones relacionadas