Framewors Ligeros y Lógica de Negocio


Introducción

Clásicamente hay dos formas de organizar la lógica de negocio: diseño procedimental u orientado a objetos (OO).

El diseño procedimental organiza el código en funciones y estructuras de datos simples. Las estructuras de datos, generalmente se crean, se inicializan y se pasan como parámetros a las funciones. La relación entre estas funciones y los datos que utilizan suelen asociarse en librerías según el criterio del programador.

Por el contrario, la aproximación orientada a objetos organiza el código en objetos que contienen ambos aspectos, datos y comportamiento. Dichos objetos colaboran, generalmente mediante herencia o composición para resolver la lógica de la aplicación. La relación entre los datos y las funciones que los usan está mantenida en su mayor parte por el propio lenguaje. Generalmente el diseño orientado a objetos es más fácil de entender, mantener, extender y probar.

A pesar de los beneficios del diseño OO, muchas aplicaciones J2EE modernas se han escrito utilizando el estilo procedimental. Uno de los precursores principales de dicho estilo fue la especificación EJB (anterior a 3.0).

Los principales atractivos del estilo procedimental son:

El sistema funciona bien con lógicas de negocio simples pero a medida que esta se complica, los scripts transaccionales suelen contener miles de lineas de código. Se promueve la duplicación de código, los programadores tenderán a programar para si mismos debido a la dificultad de encontrar los métodos disponibles para cada modelo de datos. Se pierde el principal atractivo de la omisión del diseño. El sistema se hace demasiado dificil de entender, probar y mantener.

Vuelta a OO

En los últimos años podemos hablar de una recuperación del diseño OO fomentado por autores que o bien no compartieron en entusiasmo general de EJB o bien desilusionados por los resultados que EJB proporciona en aplicaciones con una lógica de negocio medianamente complejas.

Considerablemente anterior a la nueva especificación EJB 3.0 aparecieron algunos frameworks que recuperaban el diseño OO mediante objetos que no implementaban ninguna de las interfaces específicas de EJB. Martin Fowler, Rebbecca Parsons y Josh MacKenzie acuñaron el nombre de POJO (Plain Old Java Object) para dar un nombre atractivo al desarrollo de aplicaciones basados en objetos java regulares no vinculados a un contenedor EJB.

Fowler, en su excelente libro Patterns of Enterprise Application Architecture (2002), identifica como Modelo del Dominio (Domain Model) al conjunto de clases, normalmente pequeñas que contienen tanto estado como comportamiento y que constituyen la base de la capa de de negocio (Evans - Domain Driven Design). Los modelos sin comportamiento, similares a los entity beans de EJB 2.0, se identifican en esta linea de desarrollo como el anti-patrón Anemic Domain Model (ADM) en oposición al patrón Rich Domain Model (RDM) donde los servicios delegan gran parte de la lógica de la aplicación a los modelos del Dominio.

En modelos medianamente complejos, el estado de los modelos del dominio se hace persistente mediante un framework ORM (Object/Relational Mapping) de persistencia, como JDO, Hibernate o TopLink. La configuración de los modelos del dominio se realiza forma declarativa mediante un contenedor IoC como Spring o PicoContainer. Por último, los servicios basados en POJOs proveen capacidades similares a un contenedor EJB, como sguridad y transacciones declarativas, mediante el uso de AOP.

Esta arquitectura, conocida como arquitectura de contenedor ligero (Lightweight Container Architecture) fué analizada en detalle por Rod Johnson (autor del framework Spring) en su best-seller J2EE Design and Development (Wrox, 2002) y posteriormente contrastada seriamente con la especificación EJB en J2EE Development without EJB (Wrox, 2004).


Frameworks Ligeros. (Lightweight Containers)

La capa de presentación la proporciona un Framework MVC (Modelo – Vista – Controlador) que puede ser dedicado (Struts o Webwork) bien provisto por el propio contenedor IoC (Spring).

La capa de negocio la forman Servicios que son implementados por objetos de negocio mediante POJOS sobre los que se utilizan técnicas de Programación Orientada a Aspectos (AOP, Aspect Object Programing) para proveer la funcionalidad de contenedores clásicos EJB como, por ejemplo, transacionalidad declarativa. Estos servicios, delegan gran parte de la lógica del negocio en los modelos del dominio, que se intercambian entre todas las capas.

La capa de integración se realiza mediante persistencia transparente utlizando un framework de O/R Mapping como Hibernate.

Todas las capas se ejecutan en una única Maquina Virtual. El Contenedor IoC es es responsable de del emsamblaje de los objetos mediante inyección de las dependicias al inicio de de la aplicación.

Es evidente que al compartir todas las capas los modelos del dominio y estos contener comportamiento (en oposición a intercambiar DTOs o XML) existe un acoplación entre capas y estas son difícilmente distribuibles en máquinas virtuales separadas. Es el precio que hay que pagar por recuperar el diseño orientado a objetos.

Sin embargo la distribución transparente proporcionada por EJB es engorrosa, cara y en muchos casos inútil. Ud. no compraría un autobús en lugar de un automóvil por si alguna vez se da el caso de que tiene que llevar a veinte amigos. Del mismo modo no debería programar aplicaciones distribuidas cuando realmente no las necesita. En la mayoría de los casos es más efectivo escalar las aplicaciones mediante hardware, utilizando clusters, por ejemplo. Si realmente necesita distribuir algunos servicios esto puede hacerse mediante servicios web, no de forma generalizada para toda la aplicación.

Ventajas principales de la arquitectura de Framework ligero.



Estilo procedimental OO, Domain Model
Implementación EJB POJOs
Transacciones Declarativas CMT Spring, AOP
Emsamblaje de la aplicación JNDI Inyección de Dependencias, Spring


Conclusiones

La especificación EJB prometía simplificar el desarrollo de aplicaciones, sin embargo aunque elimina alguna complejidad, introduce serios problemas específicos de la arquitectura EJB como la distribución transparente (DTOs) o la separación del comportamiento y del estado persistente (Entity Beans). Una buena parte de los patrones de diseño que se utilizan en una aplicación EJB clásica no son más que paliativos de las desventajas introducidas por la propia especificación.

La reciente especificación EJB 3.0 no ha hecho oídos sordos al movimiento en pro de los frameworks ligeros liderados principalmente por Spring como contendor IoC e Hibernate como ORM. El hecho de que la nueva revisión de la especificación siga las preferencias de los desarrolladores y no al contrario, es un paso muy importante en la dirección correcta. La especificación anterior hizo estándar algo nuevo y se impuso como modelo a seguir sin apenas haberse probado. Miles de programadores en todo el mundo se lanzaron a programar utilizando el estándar EJB sin reparar en las consecuencias de seguir un estándar que debía ser bueno “a priori”.

Aunque hoy día un número considerable de desarrolladores basan sus aplicaciones en frameworks ligeros, fundamentalmente Spring, a menudo se siguen utilizando modelos anémicos donde simplemente se han sustituido las capacidades del contendor EJB. Los Entity Beans por POJOs, los Session Beans por servicios basados en POJOs, JNDI por Inyección de dependencias (IoC), CMP por ORM como Hibernate, TopLink o JDO y CMT por Proxys Transaccionales AOP. Sin embargo el código sigue siendo principalmente procedimental. Se puede observar que el anti-patron ADM ha sobrevivido a su precursor, EJB 2.0 CMP (actualmente sustituido por JPA) mientras que el verdadero corazón de la capa de negocio de esta arquitectura, Rich Domain Model, no ha llegado tan lejos como los propios frameworks que la soportan.

Acrónimos


Bibliografía