Veamos un ejemplo simple de tipos de cambios, donde se nos solicita el servicio de Captura de Operaciones de compra-venta de dólares hacia otras instituciones bancarias. La figura 1 muestra cómo podría diseñarse este servicio con un Session EJB.
El acceso hacia los objetos de datos (Data Access Object - DAO) es a través de un EJB llamado CapturaService, donde cualquier validación y/o proceso de lógica de negocio es ejecutada. Por ejemplo, si la institución bancaria existe, o si la cantidad que se desea cambiar está dentro de los límites aceptables.
El resultado es un objeto de datos llamado CapturaResultDTO con el resultado de la operación. Los métodos que acceden la base de datos están encapsulados en DAOs, los cuales pueden ser implementados con JDBC o algún otro mecanismo de persistencia. Este diseño aparenta estar bastante bien, pero esconde varios problemas que describo a continuación.

Figura 1. Diseño de Captura de Operaciones con EJB 2.
Problemas frecuentes en EJBs
Framework pesado y complejo. EJB 2 es un framework muy completo, que resuelve requerimientos comunes en las aplicaciones empresariales, tales como el manejo de transacciones distribuidas, seguridad y persistencia. Esto trae varias ventajas, pero también lo convierte en un modelo muy pesado y complejo.
Poca productividad. La arquitectura EJB 2 nació con el propósito de facilitar el desarrollo de aplicaciones empresariales, y ciertamente nos evita la necesidad de codificar procesos estructurales de bajo nivel, pero esa ayuda se paga con altísimos costos de tiempo. Hacer cualquier modificación a un EJB, requiere además de editar y compilar, instalar cada componente EJB en el Servidor de Aplicaciones, configurar los archivos XML, levantar el Servidor de Aplicaciones para que se tomen los cambios, y buscar soluciones a problemas generados por los mismos EJBs.
No fomenta la Orientación a Objetos
Mucha gente piensa que por el hecho de escribir código en un lenguaje que soporte OO, ya están desarrollando con objetos y todo el paradigma que éste conlleva. Sin embargo, lo anterior no es una estrategia basada en tecnología, sino en la organización del código. La cultura de la programación orientada a componentes de EJB 2, no fomenta la orientación a objetos, ya que los session y message-driven beans son estructuras monolíticas y clases muy pesadas. Por otro lado, los Entity Beans que son creados para representar entidades de negocio, tienen muchas limitaciones que los hacen difíciles para implementar un modelo de objetos. Como resultado, es difícil desarrollar un verdadero estilo Orientado a Objetos sobre la plataforma J2EE. Este tipo de desarrollos es lo que Martin Fowler llama “anemia domain model”, y parecido a la falta de vitalidad en la sangre anémica, los modelos de objeto anémicos únicamente modelan superficialmente el problema, ya que contienen clases que implementan poco, o nada de comportamientos.
Desarrollando con POJOs y Frameworks ligeros
Antes de la especificación EJB 3, muchos desarrolladores desilusionados con EJB buscaron alternativas, y encontraron que los POJO son una de esas, convincente a EJBs. Un POJO (Plain Old Java Object) es simplemente un objeto de Java que no implementa ninguna interfase especial. Su nombre fue creado por Fowler, Rebbecca Parsons y Josh MacKenzie para darle a los objetos regulares de Java un nombre de sonido divertido.
Los POJOs por sí solos, no son suficientes para crear una aplicación empresarial completa, ya que carecen de los servicios que brinda un contenedor de EJB. Por eso, la solución es complementarlos con el uso de Frameworks Ligeros como Spring e Hibernate, que reemplazan algunas de las partes pesadas de la plataforma J2EE. Hibernate y Spring tienen características importantes, el no ser intrusivas, es una de ellas. Proveen transacciones y persistencia sin requerir que las clases implementen ninguna interfase en especial (por ello siguen siendo POJOs). La aplicación es ensamblada con contenedores ligeros que implementen Dependecy Injection en lugar de usar la búsqueda de componentes con JNDI.
Estos frameworks solucionan diferentes necesidades a lo largo de un desarrollo empresarial. Los beneficios son mayores cuando se combinan adecuadamente con patrones de diseño y mejores prácticas de desarrollo. Por ejemplo, el patrón de Modelo de Domino nos brinda todo el beneficio del Desarrollo OO, ya que las reglas de negocios son la base de la implementación, al tiempo que los objetos de dominio ignoran que serán persistidos, ya que, transparentemente son mapeados hacia la Base de Datos relacional. Un framework de persistencia como Hibernate nos brinda una solución ORM (Object-Relational Mapping), y si se requiere mapear POJOs hacia sentencias SQL, iBATIS, nos brinda una solución bastante conveniente para ejecutar sentencias SQL. Con un el uso de interfaces se evita acoplar un modelo de dominio hacia un framework de persistencia específico, lo que nos da mayor flexibilidad e incluso es posible probar el modelo de domino sin un esquema de Base de Datos. El desarrollo con POJOs también nos brinda un beneficio extra, ya que el Desarrollo Orientado-a-Pruebas (Test Driven Development - TDD) es bastante simple y compatible con los POJOs, al no depender de un servidor de aplicaciones.
Tal vez la principal razón para usar Session Beans, es la capacidad de tener transacciones administradas por el contenedor (Container-Managed Transaction - CMT). Esto permite que el contenedor EJB automáticamente comience una transacción cuando un método es invocado, haciendo el commit cuando termina exitosamente, o el rollback en caso de no ser así. Ahora bien, si optamos por la opción de POJOS y frameworks ligeros, el framework de Spring nos provee una solución equivalente a CMT para POJOs, además de tener un rango amplio de características que lo hacen muy fácil de usar. Cuando un método POJO es llamado, Spring automáticamente comenzará una transacción y hará el commit o rollback correspondiente. Aquí lo interesante es que Spring puede administrar las transacciones usando el framework de persistencia, el administrador de transacciones de JDBC, o el Java Transaction API (JTA), según sea deseado. Esto es tan simple como definir un POJO como un Spring Bean, con unas cuantas líneas de XML similar al deployment descriptor de EJB, y con eso tenemos un POJO que es transaccional. La aplicación obtiene un SpringBean llamando a la fábrica de SpringBean con el nombre y tipo esperado. Tan simple como:
BeanFactory factory = new XMLBeanFactory(new FileInputSteam(“capturaFacade.xml”)) ;
CapturaFacade cF = (CapturaFacade) factory.getBean(“CapturaFacade”, CapturaFacade.class);
Nota: Utilizamos un Façade con la intención de desacoplar las responsabilidades de un CapturaService y la capa de presentación.
Debido al alto nivel de configuracion de Spring, la fábrica de SpringBean puede ser configurada para regresar un proxy en lugar del objeto original. Este proxy, también conocido como interceptor, es un objeto que finge ser el objeto original, pero que puede ejecutar código adicional antes y después de la invocación del objeto original, y por tanto sirve para muchos propósitos, como administrar transacciones, seguridad o conexiones a la base de datos. CapturaFaçade puede ser envuelto en un interceptor, el cual administra las transacciones con algún administrador de transacciones propio del framework de persistencia que estemos usando.
Diseño basado en POJOs
Revisemos por último el diseño del servicio de Captura de Operaciones de compra-venta de dólares, pero ahora con POJOs. Este diseño tiene más componentes que el basado en EJB, y puede parecer más complejo, pero su diseño es más modular y mucho más fácil de probar y extender. Aun cuando son más clases, cada una tiene un pequeño número de responsabilidades fáciles de entender y bien definidas.
Se agregó un nuevo modulo CantidadPolicy, donde aplicamos políticas de filtro que tengan que ver con la cantidad que se compra o vende. Esto es más que nada, un ejemplo de lo fácil que se puede agregar nueva funcionalidad, es decir, un objeto con responsabilidad simple y específica.

Figura 2. Diseño del servicio usando POJOs.
Usamos interfaces para simplificar el desarrollo orientado a pruebas, ya que es posible reemplazar la implementación del repositorio Hibernate por algún otro framework de persistencia, sin modificar el código.
En resumen, los frameworks ligeros como Spring e Hibernate nos permiten usar POJOs, con todas sus conveniencias; y tener los mismos beneficios de usar EJB Session Beans, sin tener sus complicaciones.
Acerca del autor
Ixcoatl Pérez es Consultor TI especializado en sector financiero, con experiencia desarrollando sistemas empresariales para diferentes industrias en USA y México. Es experto en análisis y diseño orientado a objetos, desarrollo web, RUP y arquitectura J2EE. Ixcoatl cuenta con las certificaciones Sun Certified Java Developer, Sun Certified Web Component Developer y Sun Certified Business Component Developer.
- Log in to post comments