07 noviembre, 2006

Inversión del Contról - Spring

El patrón de diseño de "Inversión del Contról" (Inversion of Control) o "Inyección de Dependencia" (Dependency Injection) permite invertir el camino en el que un objeto obtiene las referencias a otros objetos de los cuales depende.

Es decir: si un objeto X depende de otro objeto Y. A su vez, Y depende de Z, un container (o motor de inyección) le proveerá a X una instancia de Y y a este una instancia de Z.

Utilizaremos el framework Spring para resolver las dependencias entre las diferentes clases.


Repaso de Nuestra Aplicación

En la aplicación que analizamos en los capítulos anteriores trabajamos con estos objetos y sus respectivas dependencias:



El gráfico muestra que el usuario creaba una conexión con la base de datos y luego obtenía una instancia de Facade. Todos los métodos de Facade recibían la conexión por lo tanto el usuario se la pasaba como parámetro.

A su vez, Facade resolvía sus métodos utilizando los objetos de negocio Dept y Emp. Estos también necesitaban la conexión a la base de datos por lo tanto el facade (que la recibía) se las pasaba como parámetro en los métodos que invocaba.

Analizando esto podemos deducir lo siguiente:
  • Ni el usuario (main()) ni el facade necesitan la conexión.
  • El usuario depende de Facade
  • Facade depende de Emp y Dept
  • Emp y Dept dependen de la conexión a la base de datos
Definiremos estas relaciones de dependencia en el siguiente archivo xml.



Podemos ver que definimos un bean facade cuya clase de implementación es demo.imple.FacadeSpring. Tiene dependencias con los beans dept y emp.

Luego definimos los beans dept y emp los cuales tienen dependencia con el bean OracleDS (un DataSource).

Redefiniremos las interfaces Facade, Dept y Emp para eliminar el parámetro Connection de todos sus métodos ya que el container (String) “inyectará” la conexión a los objetos que la necesiten.







Veamos ahora la implementación de Emp (EmpImple.java) modificada. Simplemente eliminamos el parámetro con de todos los métodos heredados de Emp y agregamos un atributo DataSourse ds y su correspondiente setter setDs() para que el container (Spring) pueda setearle el data source.



Veamos ahora la implementación de Facade: FacadeSpring.java.

Notemos que simplemente utilizamos los objetos dept y emp. Ni siquiera necesitamos utilizar la (vieja) clase DomainFactory para obtenerlos. Spring los “inyectará” (a través de los setters) al momento de crear la instancia de Facade.



Por último veamos un main() (cliente) que instancie a Facade y le invoque algún método.



Si queremos podemos abstraernos en el main() de la clase XmlBeanFactory modificando FacadeFactory para obtener allí la instancia de Facade.