Patrón de Inyección de dependencias

0
28996

Patrón de Inyección de
dependencias

 

Patrón de Inyección de dependencias. 1

Introducción. 1

Diseños tradicionales. 2

Diseñando nuestro patrón de inyección de dependencias
DependencyInyector
. 2

Esquema de funcionamiento. 3

Ejemplo de implementación en Java 5. 3

Init.java. 3

InstanceA.java. 3

InstanceB.jave. 4

DependencyInjector.java. 4

InstanceConfigurationReader.java. 5

InstanceConfiguration.java. 6

ParameterConfiguration.java. 7

InstanceCrearor.java. 7

InstanceConfigurator.java. 8

Instance-Config.xml 9

Conclusión. 10

 

  English Version: The dependency Injector Pattern

Introducción

En el desarrollo de software moderno se
ha comenzado a generalizar el uso de patrones para implementar partes de
nuestros desarrollos. Los patrones proponen soluciones estándares a los
problemas comunes de diseño de nuestras aplicaciones. Hay muchos patrones
diferentes, aunque sin duda los más famosos son los conocidos como patrones
“GoF”.

Realmente podemos  definir nosotros
mismos otros patrones , siempre que encontremos una solución estándar a un
problema común.

 

 

En este artículo os voy a mostrar un patrón
muy sencillo, el patrón “inyector de dependencias”, muy utilizado últimamente
en los desarrollos de software modernos, sobre todo en el mundo “Open Source”
de Java. Este patrón a su vez deriva de uno más genérico, el patrón
de “inversión del control” de Larman.

 

Como siempre, lo primero que vamos a
describir es el problema.  El escenario del que vamos a partir es el siguiente:

·      
Una clase A está implementando una cierta
funcionalidad de la aplicación. Como ejemplo podría ser una cierta funcionalidad
de la lógica de negocio.

·      
Para completar dicha funcionalidad usa una
clase B de utilidad. Es el caso habitual de las clases que implementan la
persistencia de los objetos en la base de datos.

·      
Para realizar su función, la clase B utiliza
otra clase S que le permite el acceso a otros recursos, en nuestro ejemplo será
la clase de conexión al gestor de la base de datos.

 

Diseños tradicionales

Normalmente en los diseños habituales, la
clase B de utilidad tiene una relación de uso de la clase S, por lo que para
poder utilizarla debe cumplir dos cosas:

  • debe conocer su tipo
  • debe poder obtener una instancia de la
    clase S.

 

Esto introduce una relación de
dependencia, al menos en la dirección B->S, entre ambas clases. Para poder minimizar
el impacto de dicha dependencia podemos recurrir a varias soluciones.

  • Con respecto al tipo, podemos utilizar
    el patrón de Interfaz para la clase S, es decir, que B conocerá una interfaz
    genérica de la clase S, lo que aisla a la clase B de la implementación real
    de la clase S.
  • Ahora nos queda la segunda parte del
    problema, y es el modo en el que B obtiene una instancia de la clase S. 
    Aquí nos va a ayudar el patrón de inversión de control, que nos dice que
    la instancia de la clase S le será pasada por la clase A, es decir, los
    objetos que B necesita para completar la petición de A le son pasados a B
    como parámetros de la petición. El control sobre el objeto S pasa de la
    clase llamada B a la clase llamadora A, es decir, se ha invertido el
    control de la clase S.

 

Diseñando nuestro patrón de
inyección de dependencias DependencyInyector

Podemos crear una versión sencilla de
este patrón utilizando un diseño bastante simple.

Este patrón lo vamos a descomponer en los
siguientes objetos:

  1. DependencyInyector. Es el objeto que controla cómo se realiza la inyección de
    dependencias. Utiliza los objetos DependencyConfigarationReader,
    InstanceCreator e InstanceConfigurator. La configuración de las instancias
    la almacena en el mapa de  instanceConfugurations y las instancias en el
    mapa instances.
  2. InstanceConfigurationReader. Este objeto lee la configuración de dependencias que se va
    a utilizar. Esta configuración está compuesta de una serie de objetos que
    se deben instanciar, la lista de parámetros con su valores que se debe
    proporcionar a cada objeto para su configuración y las relaciones que se
    deben crear entre los diferentes objetos.
  3. InstanceCreator. Este es un objeto que sigue el patrón factoría, y se ocupa
    de crear instancias y ponerlas a disposición de los demás objetos del
    patrón.
  4. InstanceConfigurator. Este objeto conoce cómo se debe configurar cada uno de los
    objetos instanciados, asignándole los parámetros y relaciones.

 

 

En el diagrama se puede ver el diseño
básico del patrón. La clase principal DependencyInyector sirve como interfaz
para el conjunto. El usuario interactuará con el conjunto a través de esta
clase. Para diseñar esta clase podemos usar el patrón singleton, ya que
normalmente nos hará falta una única instancia de la misma.

Esquema de funcionamiento

Al instanciar un inyector de
dependencias, este objeto usa el objeto InstanceConfiguratorReader para que
éste obtenga la información de dependencias a utilizar. A continuación se
instancia un objeto InstanteCreator para que se puedan crear las instancias de
objetos solicitadas. Luego el DependencyInyector crea una instancia del
DependencyConfigurator y le pasa a esta instancia las referencias a los otros
objetos instanciados (inversión de control en esta instancia, como se puede
ver). Ahora es el DependencyConfigurator el responsable de ir creando
instancias de objetos, mediante el InstanceCreator, y luego irlas configurando,
según las instrucciones que reciba del DependencyConfiguration.

Ejemplo de implementación en
Java 5

Para ilustrar el patrón DependencyInjector
he creado una implementación simple en Java 5. Esta implementación se puede
probar de una manera muy sencilla sin más que crear un proyecto Java
en nuestro entorno de desarrollo y añadir los siguientes ficheros:

 

Init.java

 

Esta es la clase que crea la instancia del
inyector de dependencias.  Una vez instanciadas la clase InstanciaA y InstanciaB
muestra su contenido. Es un ejemplo simple.

 

InstanceA.java

InstanceB.jave

 

Clases de ejemplo.

DependencyInjector.java

 

La clase DependencyInjector, responsable
de coordinar la inyección de dependencias.

InstanceConfigurationReader.java

 

Clase simple para leer la información de
configuración de las dependencias.  Lee la información almacenada en un
sencillo fichero XML.

 

InstanceConfiguration.java

 

Java Bean para para amacenar la información
de configuración de dependencias.

 

ParameterConfiguration.java

 

Clase auxiliar del bean de configuración.

InstanceCrearor.java

 

Creador de instancias. Para este ejemplo
he usado una factoría abstracta muy simple.

InstanceConfigurator.java

 

Configurador de instancias. Utiliza la
información de configuración para inyectar parámetros y dependencias de otras
clases. Utiliza el mecanismo de reflexión de Java.

Instance-Config.xml

 

Fichero de configuración de las
instancias.

 

Conclusión

 

En este artículo hemos visto cómo
utilizar el patrón de inyector de dependencias, que nos permite crear instancias
de objetos y configurarlas, aislando las dependencias entre los mismos mediante
la inyección de las instancias de otros objetos como parámetros de los objetos.

Además hemos visto una implementación
simple del patrón, en Java 5, que nos permitirá añadir de manera sencilla un
inyector de dependencias a nuestros proyectos. El proceso de instanciación de
los diferentes objetos que componen nuestro sistema o aplicación se controlará
mediante un simple ficheo xml, lo que nos permitirá modificar la configuración
del mismo sin más que utilizar diferentes ficheros xml.

Este patrón nos resolverá de una manera
sencilla y elegante el ensamblado de componentes dentro de nuestra aplicación.

Además con este artículo entenderemos
mejor el esquema de funcionamiento de los contenedores de objetos actuales,
como puede ser Spring Framework y otros.

Dejar respuesta

Please enter your comment!
Please enter your name here