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:
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 ;)