Inyección de dependencias

07/11/2013

La inyección de dependencias (DI) es un patrón de diseño de componentes derivado de la Inversión del Control (IoC) implementado en Spring que está teniendo mucho éxito en los programadores de Java. Veamos el porqué.

Cuando programamos en Java, podemos decir que una clase depende de otra, cuando la primera tiene variables cuyo tipo es de la segunda y cuando la primera crea objetos de la segunda.  Normalmente usamos el operador new para crear dicha dependencia creando nuevos objetos.

Dependencias en clases con el operador new

Dependencias en clases con el operador new

›
Esta manera de programar tiene varios inconvenientes:
›
  • ›1. Difícil mantenimiento y re-diseño: En tiempo de diseño, cualquier cambio realizado en las clases, puede afectar a las clases que dependen de ella y por tanto es necesario modificarlas.›
  • ›2. Menor estabilidad: En tiempo de ejecución, si falla una clase que tiene muchas dependencias, todas estas clases también fallarán.›
  • 3. Aplicaciones con un nivel de acoplamiento muy alto: tienen muchas dependencias.

Posibles soluciones:

›Desarrollar la aplicación en capas: Así por ejemplo si cambiamos el acceso a la base de datos, sólo hay que cambiar la capa de persistencia y no la capa de presentación o la lógica de negocio.
Desarrollo de software en capas

Desarrollo de software en capas

›
Utilizar interfaces: para que las variables empleadas en una parte de la aplicación no queden ligadas a una clase, sino a una interfaz, pudiendo hacer referencia a diferentes clases que implementan dicha interfaz.
Desarrollar aplicaciones usando interfaces

Desarrollar aplicaciones usando interfaces

›El desarrollo con interfaces separa claramente el qué tiene que hacerse (Interfaz) del cómo tiene que hacerse (Clase) quedando un código bastante más claro.  ›Es posible crear referencias a interfaces, aunque no pueden ser instanciadas, aunque la dependencia de creación de interfaces seguiría existiendo y aquí es donde aparece la “magia” de Spring…
›Spring es capaz de hacer desaparecer los operadores new mediante la inversión del control (IoC):
›1. Obtiene los objetos mediante una clave a través de un contexto.
›2. Asigna el objeto por el contexto mediante un método set.
›

Spring hace desaparecer el operador new usando IoC

Spring hace desaparecer el operador new usando IoC

›De esta forma desaparecen de la clase A todas las referencias de la clase B.
›La Inversión del control es el patrón más característico de Spring, que permite eliminar las dependencias entre los objetos de la aplicación. Dichas dependencias se centralizan en un archivo de configuración. ›La aplicación no crea los objetos, sino es la factoría de Beans quien los crea y elimina. La aplicación solicita a la factoría de Beans una referencia al objeto y es la factoría quien lo crea. La aplicación guarda una referencia al objeto y la usa. Por ejemplo con este código estaríamos buscando en la factoría, un bean denominado personas. Una vez obtenida dicha referencia, ya podemos añadir sus propiedades.

 ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(“applicationContext.xml”);
PersonaInterface persona = (PersonaInterface) ctx.getBean(“personas”);
persona.setId(1);
persona.setNombre(“Pedro”);

›
›La factoría es quien decide crear (justo en ese momento) los objetos dependiendo de un archivo xml de configuración. Por tanto si hay que hacer un cambio en la clase a implementar, sólo necesitaremos cambiar el archivo xml.
Para que Spring pueda encontrar el bean “personas”, previamente debemos haberlo declarado en un fichero xml de configuración.  ›El archivo de configuración xml de una aplicación de Spring sirve para declarar los beans de la aplicación que se asocian a objetos simples de Java (POJOs). Los contextos se pueden parametrizar desde el propio xml para configurar propiedades de los objetos.

<bean id=“personas” class=“com.aplicacion.beans.Personas”>
  <property name=“nombre” value=“juan”/>
</bean>

El bean persona pertenece a una clase que ha sido desarrollada como un POJO, osea lo más simple posible: con sus propiedades internas, sus getters y sus setters.

POJO: Clase muy simple con sus getters y setters

POJO: Clase muy simple con sus getters y setters

Con la Inversión del control de Spring se obtienen dos grandes ventajas:

  • Separamos la lógica de negocio desarrollando objetos simples (POJOs) que además no dependen de interfaces complejas, simplificando claramente el código.
  • Desarrollamos objetos que no tienen dependencias del resto de objetos, con lo que el código es más fácil de reutilizar y probar.

Veamos un ejemplo:

Tenemos declarado un interfaz muy sencillo denominado Participante con un método:

package com.ejemplospring.beans;

     public interface Participante {
          void actuar();
     }

y una clase denominada Malabarista que implementa dicha interfaz:

package com.ejemplospring.beans;

public class Malabarista implements Participante {

     private int bolas=3;

     public Malabarista(){}

     public Malabarista (int beanbolas){
            this.bolas = beanbolas;
     }

      public void actuar(){
            System.out.println(“Malabarista actuando con ” + bolas + ” bolas”);
     }

}

Ahora declaramos en el fichero de configuración xml de Spring, un Malabarista en concreto denominado “jose”

<?xml version=”1.0″ encoding=”UTF-8″?>

<beans xmlns=”http://www.springframework.org/schema/beans&#8221;
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;
xsi:schemaLocation=”http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd”&gt;

<bean id=”jose” class=”com.ejemplospring.beans.Malabarista” />
</beans>

Finalmente declaramos una clase DI en la que declaramos un contexto de Spring y solicitamos de la factoría de beans el Malabarista “jose”.

package com.ejemplospring;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.ejemplospring.beans.Participante;

public class DI {

     public static void main(String[] args) {

          ApplicationContext ctx = new ClassPathXmlApplicationContext(
          “com/ejemplospring/beans.xml”);
          Participante participante = (Participante)ctx.getBean(“jose”);
          participante.actuar();

     }

}

Esta es la salida en Java:

Salida de la carga del bean en Spring

Salida de la carga del bean en Spring

En el momento de llamar al bean en el contexto, es en ese momento cuando Spring crea el objeto por nosotros y vemos que podemos llamar a su método actuar y vemos la salida en pantalla. Como vemos en el código, en ningún momento hemos necesitado crear un nuevo objeto con new, sino es el contexto de Spring, el que crea los objetos cuando los necesita la aplicación.

Para aprender más, podemos usar esta url con la documentación oficial de Spring sobre la Inversión del Control (IOC):

http://www.springframework.net/doc-latest/reference/html/objects.html

Una respuesta to “Inyección de dependencias”


Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: