2.3.1 Value Object
Value Object (1) Intención Agrupar un conjunto de atributos procedentes de uno o varios objetos del dominio También conocido como Recientemente se le ha cambiado el nombre a Transfer Object Data Transfer Object, Replicate Object Motivación En MiniBank necesitamos acceder a los datos de las cuentas y operaciones bancarias AccountVO (from vo) <<Interface>> SQLAccountDAO - accountidentifier : Long - useridentifier : Long - balance : double + AccountVO(accountIdentifier : Long, useridentifier : Long, balance : double) + getaccountidentifier() : Long + getuseridentifier() : Long + getbalance() : double + setbalance(newbalance : double) : void + tostring() : String
Value Object (2) Aplicabilidad Cuando necesitemos representar un conjunto de atributos procedentes de uno o varios objetos del dominio Estructura <<interface>> java.io.serializable <<interface>> DAO - atributos VO + métodos get/set
Participantes VO (AccountVO) Value Object (3) Ofrece métodos get/set para acceder a sus atributos DAO (SQLAccountVO) Tiene acceso a los valores que se copian en el VO Los Session Facade (Business Delegate) también trabajan con VOs Colaboraciones Un DAO devuelve VOs en sus métodos findxxx, y los recibe en sus métodos create y update Consecuencias Beneficios En el contexto de EJB, eficiencia En el contexto de JDBC, poder representar un conjunto de atributos procedentes de uno o varios objetos del dominio Riesgos Un VO puede contener información obsoleta si se pretende usar en una actualización posterior en otra transacción => EJB Design Patterns discute el patrón Version Number
Value Object (4) Implementación Domain Value Object Un Value Object es un Domain Value Object cuando su atributos corresponden a los de un objeto del dominio Ejs.: AccountVO y AccountOperationVO en MiniBank Problemas: Fuerte acoplamiento entre las clases cliente de los Session Facades (Business Delegates) y el modelo de objetos del dominio Diferentes interfaces de usuario (IUs) pueden requerir sólo un subconjunto de los atributos de un VO o un conjunto de atributos de distintos VOs Ej-1: CarVO con 100 atributos y tenemos un IU en el que sólo queremos mostrar los relativos al motor (10 atributos) Ej-2: Un IU que sólo quiere mostrar los atributos relativos al motor de un determinado coche y los de su fabricante (ManufacturerVO)
Value Object (5) Custom Value Object Solución al ej-1: SessionFacade + findcarengine(carid) : CarEngineVO <<interface>> CarDAO + find(con, carid) : CarVO CarVO CarEngineVO SessionFacade Solución al ej-2: <<interface>> CarDAO CarVO + findcarengineandmanufacturer(carid) : CarEngineAndManufacturerVO CarEngineAndManufacturerVO + find(con, carid) : CarVO <<interface>> ManufacturerDAO + find(con, manid) : ManufacturerVO ManufacturerVO
Value Object (6) Custom Value Object (cont) CarEngineVO y CarEngineAndManufacturerVO son Custom Value Objects (son específicos a casos de uso) Sólo tienen los atributos necesarios CarEngineAndManufacturerVO debería implementarse (en este caso) como un objeto compuesto de un CarEngineVO y un ManufacturerVO Se usan en las fachadas del modelo, pero no en los DAOs Las fachadas del modelo no son reusables entre aplicaciones, dado que implementan casos de uso específicos a la aplicación Los Custom Value Objects se diseñan para dar soporte a casos de uso específicos Los DAOs sólo trabajan con Domain Value Objects, y en consecuencia son reusables entre aplicaciones (ej.: una tienda de comercio electrónico y su aplicación de administración comparten gran parte de los DAOs)
Custom Value Object (cont) Value Object (7) Otro ejemplo: OrderVO es Custom Value Object SessionFacade + findorder(orderid) : OrderVO + findorderdetails(orderid) : OrderDetailsVO + findlineitems(orderid) : Collection + updatelineitem(lineitemvo):void + etc. OrderVO - details : OrderDetailsVO - lineitems : Collection OrderDetailsDAO 1 0..n LineItemDAO OrderDetailsVO - orderidentifier : Long - loginname : String - date : Calendar - shippingaddress : String LineItemVO - lineitemidentifier : Long - orderidentifier : Long - productidentifier : Long - quantity : int - status : String
Value Object (8) Data Transfer HashMap En una aplicación de tamaño medio puede que se necesiten un número desmesurado de Value Objects => Problema de mantenimiento Solución => usar mapas (ej.: HashMap) para almacenar un conjunto de pares <nombre-atributo, valor> en vez de las clases usadas hasta ahora Ej.: Map carengine = sessionfacade.findcarengine(carid); int horsepower = ((Integer) carengine.get( car.engine.horsepower )).intvalue(); String type = (String) carengine.get( car.engine.type ); Problemas Se necesitan establecer convenciones de nombrado para los atributos No es una solución fuertemente tipada
Value Object (9) Qué variante usar? Para aplicaciones pequeñas puede ser suficiente con Domain Value Objects Normalmente tienen atributos privados y métodos públicos getxxx y setxxx (para los atributos modificables) Aplicaciones de tamaño medio pueden requerir el uso de Custom Value Objects (además de Domain Value Objects) Lógicamente, sólo tiene sentido definir Domain Value Objects para aquellas IUs (casos de uso) que requieren atributos de varios objetos del dominio, o existe una diferencia importante entre los atributos que quiere visualizar la IU y los que tiene el objeto del dominio correspondiente Para IUs de actualización de datos normalmente sólo se usan Domain Value Objects Las IUs de actualización no suelen permitir actualizar datos de más de un objeto del dominio
Value Object (10) Qué variante usar? (cont) Para IUs que sólo muestran datos, pueden necesitarse Domain Value Objects En consecuencia, un Custom Value Object sólo debería tener métodos getxxx En aplicaciones muy grandes, la única alternativa puede ser usar HashMaps Enfoque que se suele seguir Cuando se empieza un proyecto suele estar claro el modelo de objetos del dominio, pero no los datos exactos que van a mostrar las IUs => se empieza trabajando sólo con Domain Value Objects A medida que avanza el proyecto (y se conocen más detalles sobre las IUs) => se refactorizan los métodos que sea preciso en los Session Facade para que devuelvan Custom Value Objects En casos extremos => HashMaps
Value Object (y 11) Código de ejemplo Véase es.udc.fbellas.j2ee.minibank.model.account.v o.acountvo y es.udc.fbellas.j2ee.minibank.model.accountop eration.vo.acountoperationvo en MiniBank Patrones relacionados Page-by-Page Iterator Session Facade