lunes, febrero 07, 2011

DDD, Spring y AspectJ: inyección de depencias (I)

El paradigma de orentación a objetos promueve que los objetos deberían tener datos y comportamiento. Sin embargo, en la realidad esto no se cumple en muchas ocasiones; especialmente en los objetos de dominio, donde habitualmente las clases se convierten en meros contenedores de información que se van pasando de unas capas a otras, delegando la funcionalidad en capas de servicio externas, creando un modelo anémico (para más información podéis acudir a http://www.martinfowler.com/bliki/AnemicDomainModel.html).

A lo largo de las siguientes entradas promoveremos el paradigma de diseño dirigido por dominio y analizaremos como podremos enriquecer nuestros objetos de dominio mediante la inyección de dependencias. Para aquellos que estéis familiarizados con las últimas versiones de Spring, estas entradas no serán más que un paseo por los internals de @Configurable (anotación que podemos encontrar las versiones más recientes de este popular framework) unidos a un poco de teoría.

Imaginemos por un momento que estamos desorrollando una tienda online para la venta de libros electrónicos y que la siguiente clase modela nuestra entidad de dominio libro. Como podemos observar estamos delegando el cálculo del precio del libro en una clase independiente la cual será la encargada de realizar los cálculos necesarios (de este modo podremos configurar el precio del libro en función de nuestras necesidades). Y ahora: ¿cómo llevamos a cabo la inicialización del atributo pricingStrategy ?

Desde aquí vamos a promover el uso de inyección de dependencias, de manera que añadiendo la infraestructura necesaria (en ese caso un simple setter para el atributo en cuestión) podremos delegar en un contenedor la responsabilidad de inyectar las dependencias necesarias en el momento en el que se instancie nuestro objeto. Siguiendo esta filosofía podríamos intercambiar las estrategias de cálculo de precios sin más que realizar una ligera modificación en la configuración, sin la necesidad de modificar nuestro código fuente. Este enfoque también nos permite llevar a cabo nuestras pruebas unitarias de manera extremadamente sencilla.

Antes de comenzar a escribir nuestros propios aspectos (lo dejaremos para la próxima entrada) veamos cómo podríamos inyectar las dependencias en nuestro objeto de dominio mediante el uso de spring y un poco de configuración.

En primer lugar tendremos que indicarle a spring que nuestra clase de dominio Book necesita que sus dependencias sean inyectadas: para ello anotamos la definición de nuestra clase con @Configurable y añadimos un setter para nuestro atributo de clase pricingStrategy. Adicionalmente, anotaremos  el setter anterior (o la propiedad) con @Autowired. Finalmente, definiremos en el contexto de aplicación de spring una implementación concreta del interfaz PricingStrategy e indicamos que estamos haciendo uso @Configurable mediante la instrucción .

Con la sencilla configuración anterior, cada vez que instanciemos un objeto de la clase Book mediante el operador new: Book book = new Book() el atributo pricingStrategy será inyectado con la referencia adecuada.

El uso de @Configurable hace uso de la reflectividad por lo que en aquellos objetos que se instancian muy a menudo podríamos incurrir en un serio problema de rendimiento. Adicionalmente, el uso de esta anotación acopla nuestro código a Spring, creando una dependencia hacia el framework.

En la siguiente entrada analizaremos el uso de interfaces de dominio y escribiremos nuestros propios aspectos como alternativa a la solución presentada a lo largo de esta entrada.


No hay comentarios: