Composite Entity
Contexto
Los beans de entidad no tienen como intención representar a cada objeto persistente en el modelo de objeto.
Los beans de entidad son más apropiados para los objetos de modelo de negocio persistentes de grano grueso.
Problema
En las aplicaciones J2EE, los clientes (aplicaciones, JSPs, servlets y JavaBeans) accesan a los entity beans a través de sus interfaces remotas. Así, cada invocación de cliente se enruta a través de networks stubs y esqueletos, aún si el cliente y el enterprise bean estén en la misma JVM, SO o máquina física. Cuando los beans de entidad son objetos de grano fino, los clientes tienden a invocar a más métodos de entity beans, resultando en una alta carga en la red.
Los beans de entidad representan objetos de negocio persistentes y distribuidos. Si se está desarrollando o migrando una aplicación a J2EE, la granularidad de los objetos es importante al momento de decidir qué debe ser implementado como un entity bean. Los entity beans deberían representar objetos de negocio de grano grueso, aquellos que proveen comportamiento complejo, más allá del comportamiento getter y setter de variables de instancia. Estos objetos de grano grueso típicamente tienen objetos dependientes. Un objeto dependiente es un objeto que no tiene dominio real cuando no está asociado con su padre de grano grueso.
Un problema recurrente es el mapeo directo del modelo de objeto a un modelo EJB (específicamente a los entity beans). Esto crea una relación entre los objetos entity beans sin consideración de la granularidad de los objetos: hay objetos de grano fino(dependientes) y de grano grueso (que deben englobar a los de grano fino que estén utilitariamente relacionados). Determinar que funcionalidad es grano fino y de grano grueso es típicamente difícil y es mejor hacerlo mediante relaciones de modelado UML.
Hay un número de áreas impactadas por el criterio de diseño de entity beans de grano fino:
* Relaciones entre las entidades - mapear directamente un modelo de objetos a un modelo EJB no toma en consideración las relaciones entre los objetos. Las relaciones entre objetos son transformadas directamente en relaciones inter-entidad de beans. Como resultado, un entity bean podría contener una referencia remota a otro entity bean. Sin embargo, mantener referencias remotas a objetos distribuidos involucra técnicas y semánticas diferentes que mantener referencias a objetos locales. Además de incrementar la complejidad del código, reduce su flexibilidad, porque el entity bean debe cambiar si hay cambios en sus relaciones.
También, no hay garantía acerca de la validad de las referencias de los entity beans a otros entity beans a lo largo del tiempo. Dichas referencias son establecidas dinámicamente usando el objeto home de la entidad y la clave primaria para esa instancia del entity bean. Esto implica una alta carga de mantenimiento de validación de referencias para cada referencia entidad-bean-entidad-bean.
* Manejabilidad - La implementación de objetos de grano fino como entiy beans resulta en un gran número de entity beans en el sistema. Un entity bean se define usando varias clases. Por cada componente entity bean, el desarrollador debe suministrar clases para la interface home, la interface remota, la implementación del bean y la clave primaria.
Adicionalmente, el contenedor puede generar clases para soportar la implementación del entity bean. Cuando el bean es creado, estas clases son realizadas como objetos reales en el contenedor. En resumen, el contenedor crea un número de objetos para soportar cada instancia de entity bean. Grandes números de entity beans resultan en más clases y código que mantener para el equipo de desarrollo. También resulta en un gran número de objetos en el contenedor. Esto puede afectar negativamente el desempeño de la aplicación.
* Carga en la Red - Los entity beans de granularidad fina potencialmente tienen más relaciones inter-entity beans. Los entity beans son objetos distribuidos. Cuando un entity bean invoca un método en otro entity bean, la llamada es tratada potencialmente como una llamada remota por el contenedor, incluso si ambos entity beans están en el mismo contenedor o JVM. Si el número de relaciones entity-bean-entity-bean se incrementa, esto baja la escabilidad del sistema debido a una alta congestión en la red.
* Dependencia del Esquema de Base de Datos - cuando los entity beans son de granularidad fina, cada instancia de entity bean usualmente representa una única fila en la base de datos. Esto no es una aplicación apropiada del diseño del entity bean, debido que los entity beans son más apropiados para los componentes de granularidad gruesa. La implementación de entity beans de granularidad fina típicamente es una representación directa del esquema de la base de datos en el diseño del entity bean. Cuando los clientes usan estos entity beans de granularidad fina, están operando en el nivel más bajo de la base de datos, debido que cada entity bean es efectivamente una única fila. Debido que el entity modela directamente una única fila de la base de datos, los clientes se hacen dependientes del esquema de la base de datos. Cuando el esquema cambia, las definiciones de los entity beans deben cambiar también. Además, debido que los clientes están operando en la misma granularidad, ellos deben observar este cambio y reaccionar a él. Esta dependencia del esquema causa pérdida de flexibilidad e incrementa el costo de mantenimiento cada vez que los cambios en el esquema de la bd son requeridos.
* Granularidad de los Objetos (Granularidad Gruesa vs Granularidad Fina) - La granularidad de los objetos impacta la transferencia de datos entre el enterprise bean y el cliente. En la mayor parte de las aplicaciones, los clientes típicamente requieren más información que una o dos filas de una tabla. En dicho caso, implementar cada uno de estos objetos de granularidad fina como un entity bean significa que el cliente tendría que manejar las relaciones entre todos estos objetos de granularidad fina. Dependiendo de los requerimientos de data, los clientes puede que tengan que realizar muchas búsquedas para un número de entity beans para obtener la información requerida.
Fuerzas
*Los entity beans son mejor implementados como objetos de granularidad gruesa debido al alto costo asociado con cada entity bean. Cada entity bean es implementado usando varios objetos, tal como un objeto home EJB, un objeto remoto, implementación del bean y una clave primaria. Cada uno de estos objetos necesarios para implementar al entity bean es manejado por los servicios contenedores.
* Las aplicaciones que mapean directamente el esquema de la base de datos a entity beans (donde cada fila en una tabla es representada por una instancia de entity bean) tienden a tener un gran número de entity beans de grano fino. Es deseable mantener a los entity beans como entity beans de grano grueso y reducir el número de entity beans en la aplicación.
* El mapeo directo del modelo de objeto al objeto EJB resulta en entity beans de grano fino. Los entity beans de grano fino usualmente se mapean al esquema de la base de datos. Este mapeo de filas entidad-a-bd causa problemas relacionados con performance, manejabilidad, seguridad y manejo de transacciones. Las relaciones entre tablas son implementadas como relaciones entre entity beans, lo que significa que los entity beans contienen referencias a otros entity beans para implementar estar relaciones de grano fino. Es muy costoso manejar las relaciones entre entity beans, debido que estas relaciones deben ser establecidas dinámicamente usando los objetos home de entidad y las claves primarias de los enterprise beans.
*Los clientes no necesitan saber la implementación del esquema de la base de datos para usar y soportar a los entity beans. Con entity beans de grano fino, el mapeo es usualmente hecho de forma tal que cada instancia de entity bean se mapee a una única fila en la base de datos. Este mapeo de granularidad fina crea una dependencia entre el cliente y el esquema subyacente de la base de datos, debido que los clientes interactúan con los beans de grano fino y son, esencialmente, una representación directa del esquema subyacente de la base de datos. Esto resulta en un alto acoplamiento entre el esquema de la base de datos y los entity beans. Una cambio al esquema causa un cambio correspondiente al entity bean y requiere además un cambio correspondiente a los clientes.
*Hay un incremento de comunicación entre aplicaciones debido a la intercomunicación entre entity beans de granularidad fina. La comunicación excesiva inter-entity beans a menudo lleva a un cuello de botella de performance. Cada llamada al entity bean es hecha a través de la capa de red, incluso si quien llama está en el mismo espacio de direcciones que quien es llamado (esto es, tanto el cliente -que es quien llama- como el entity bean llamado están en el mismo contenedor). Aunque algunos vendedores de contenedores optimizan sus implementaciones previendo este escenario, el desarrollador no puede depender de esta optimización en todos los contenedores.
*Puede ocurrir comunicación adicional entre el cliente y los entity beans debido que el cliente puede tener que comunicarse con muchos entity-beans de granularidad fina para cumplir un requerimiento. Es deseable reducir la comunicación entre entity-beans y reducir la comunicación entre el cliente y la capa de entity beans.
Solución (A todo este Peo Obsoleto a partir de EJB 3.0)
Usar Composite Entity para modelar, representar y manejar un conjunto de objetos persistentes interrelacionados en lugar de representarlos como entity beans de grano fino individuales. Un Composite Bean representa un grafo de objetos.
Para poder entender esta solución, primero debemos definir que entendemos por objetos persistentes y discutir sus interrelaciones.
Un objeto persistente es un objeto que es guardado en algún tipo de almacén de data. Múltiples clientes usualmente comparten objetos persistentes. Los objetos persistentes pueden ser clasificados en dos tipos: objetos de grano grueso y objetos dependientes (grano fino).
Un objeto de grano grueso es auto suficiente. Tiene su propio ciclo de vida y maneja sus relaciones con otros objetos. Cada objeto de grano grueso puede referenciar o contener uno o más objetos. El objeto de grano grueso usualmente maneja los ciclos de vida de los objetos que referencia y contiene, así que estos objetos son llamados dependientes. Un objeto dependiente puede ser un objeto simple auto-contenido o puede contener otros objetos dependientes.
El ciclo de vida de un objeto dependiente está fuertemente acoplado al ciclo de vida del objeto de grano grueso. Un cliente sólo puede accesar un objeto dependiente a través del objeto de grano grueso. Eso es, los objetos dependientes no están expuestos directamente a los clientes porque su padre (el objeto de grano grueso) los maneja. Los objetos dependientes no pueden existir por si mismos. En lugar de esto, siempre necesitan tener un objeto de grano grueso para justificar su existencia.
Típicamente se puede ver la relación entre un objeto de grano grueso y uno de grano fino como un árbol. El objeto de grano grueso es la raíz del árbol (el nodo más arriba, la raíz). Cada objeto dependiente puede ser un objeto dependiente standalone (un nodo hoja) que sea hijo del objeto de grano grueso. Opcionalmente, el objeto dependiente puede tener una relación de padre-hijo con otros objetos dependientes, en cuyo caso es considerado un nodo rama.
Un bean Composite Entity puede representar un objeto de grano grueso y todos sus objetos dependientes relacionados. La agregación combina los objetos persistentes interrelacionados en una única entidad bean, reduciendo drásticamente el número de entity beans requeridos por la aplicación. Esto lleva a un entity bean de grano grueso que puede aprovechar mejor los beneficios de los entity beans que una multitud de entity beans.
Sin la solución basada en Composite Entity, hay una tendencia a ver cada objeto de grano grueso y cada objeto dependiente como un entity bean separado, llevando a un mayor número de entity beans.
Estructura
Aunque hay muchas estrategias para implementar el patrón Composite Entity, la primera que discutiremos está representada por el diagrama de clase en la Figura 1.1. Aquí el Composite Entity contiene el objeto de grano grueso y el objeto de grano grueso contiene objetos dependientes.
Diagrama de clase para un Composite Entity
Diagrama de secuencia para un Composite Entity
Participantes y Responsabilidades (Referenciados en el Diagrama de Secuencia)
CompositeEntity
El Composite Entity puede ser el objeto de grano grueso o puede contener una referencia a un objeto de grano grueso.
CoarseGrainedObject - Objeto de Grano Grueso
Un objeto de grano grueso que tiene su propio ciclo de vida y maneja sus propias relaciones a otros objetos. Un objeto de grano grueso puede ser un objeto Java contenido en el Composite Entity. Opcionalmente, como ya se dijo el Composite Entity mismo puede ser el Composite Entity.
DependentObject1, DependentObject2 y DependentObject3 - Objetos Dependientes
Un objeto dependiente es un objeto que depende del objeto de grano grueso y que tiene su ciclo de vida manejado por el objeto de grano grueso. Un objeto dependiente puede contener otros objetos dependientes y así puede haber un tree de objeto dentro del Composite Entity.
Fuente


No comments:
Post a Comment