Mostrando entradas con la etiqueta DDD. Mostrar todas las entradas
Mostrando entradas con la etiqueta DDD. Mostrar todas las entradas

lunes, febrero 21, 2011

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

En la entrada anterior analizabamos el uso de la anotación Configurable y cómo esta nos ayudaba a realizar la inyección de dependencias en nuestro objetos de dominio, ayudándonos de esta manera a realizar nuestro diseño siguiendo una filosofía orientada al dominio (podréis encontrar mucha información, artículos, referencias, ponencias, . . ., relativas a este tema en http://domaindrivendesign.org/).

Como ya comentamos anteriormente el uso de la anotación Configurable era beneficioso aunque si la clase anotada se instancia un gran número de veces podríamos incurrir en una notable pérdida de rendimiento puesto que la anotación anterior hace uso de la reflectividad. Adicionalmente, indicábamos que  otro de los "problemas" era que nuestro código estaba acoplado a la plataforma, en este caso, Spring. Durante esta entrada plantearemos otro mecanismo de inyección de dependencias en nuestros objetos de dominio: inyección basada en interfaces de dominio.

Partiendo del ejemplo analizado en el ejemplo anterior, definiremos un nuevo interface PricingStrategyClient que presentará el método setPricingStrategy(PricingyStrategy pricingStrategy) . Todas aquellas entidades de nuestro dominio que necesiten esta funcionalidad deberán implementar el interfaz anterior.

Hasta el momento no hemos anotado nuestra clase con ningún artefacto adicional (@Configurable) por lo que ahora tendremos que escribir nuestro propio aspecto para inyectar las dependencias en nuestra clase de dominio. Para llevar a cabo este trabajo extenderemos un aspecto abstracto disponible en spring-aspects-3.0.5.jar (los ejemplos de estas entradas están desarrollados con la versión 3.0.5 de Spring) de tipo GenericInterfaceDrivenDependencyInjectionAspect. De manera resumida, este aspecto base determina cuando se crea una nueva instancia (o serializa) de nuestra clase e invoca al método configureBean. Nosotros únicamente deberemos implementar el método configure tal y como se muestra en el siguiente fragmento de código:


public aspect PricingStrategyDIAspect extends
  GenericInterfaceDrivenDependencyInjectionAspect {
protected PricingStrategy pricingStrategy;
public PricingStrategy getPricingStrategy() {
return pricingStrategy;
}
public void setPricingStrategy(PricingStrategy pricingStrategy) {
this.pricingStrategy = pricingStrategy;
}
@Override
protected void configure(PricingStrategyClient bean) {
bean.setPricingStrategyClient(pricingStrategy);
}
}

Como último paso de nuestra nueva solución sólo tendremos que definir nuestro nuevo aspecto en el contexto de aplicación:
<bean id="pricingStrategy" class="com.blogspot.miguelinlas3.springexamples.ddd.domain.strategy.SimplePricingStrategy"/>

<bean class="com.blogspot.miguelinlas3.springexamples.ddd.domain.interfacedibased.PricingStrategyDIAspect"
factory-method="aspectOf">
<property name="pricingStrategy" ref="pricingStrategy"/>
</bean>
Una posible mejora sería incluir el aspecto anterior como un aspecto estático dentro del interfaz PricingStrategyClient de modo que estaríamos enfatizando la relación entre ambos aunque esto os lo dejo como ejercicio ;)

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.