Inyección de dependencias. ¿Qué es y para qué sirve?

La inyección de dependencias (DI) es un patrón de diseño que deriva de un patrón más genérico llamado Inversión de Control. DI hace uso de la modularidad y la reutilización, las cuales siempre deberíamos tener en cuenta si nuestra aplicación va a estar dotada de mayor funcionalidad. Más adelante, veremos en que consiste la Inversión de Control, pero hoy vamos a centrarnos en la DI, visto además de una manera simplista, con un ejemplo sencillo.

En el ejemplo, vamos a ver la representación de una puerta con cerradura de llave y una puerta con cerradura de código. Esta sería la representación sin el uso de DI:

Start.java

Esta es la manera tradicional de hacerlo, se crea un nuevo objeto puerta que tenga una cerradura de tipo llave por un lado y otro que tenga una cerradura de tipo código por el otro.

ObjetoPuertaLlave.java:

ObjetoCerraduraLlave.java:

ObjetoPuertaCodigo.java:

ObjetoCerraduraCodigo.java:

La salida por consola de la ejecución es la siguiente:

Obviamente esta no es la mejor manera de implementar esta representación. Ahora veremos como usar DI para hacer esto mismo pero más reutilizable, ahora sólo tendremos una clase puerta:

ObjetoPuerta.java:

Vemos como esta clase puerta es más genérica y consta de un atributo que en realidad es una interface. Ésto es básicamente la inyección de dependencias, en la que en vez de invocar instancias nuevas de objetos desde la propia clase, se invocan desde fuera, siendo pasadas como parámetros. De esta manera, este ObjetoPuerta nos servirá para representar cualquier puerta que tenga una cerradura siempre y cuando ese objeto cerradura implemente la interface que contiene ObjetoPuerta como atributo.

CerraduraInterface.java:

ObjetoCerraduraLlave.java:

ObjetoCerraduraCodigo.java:

Start.java:

La salida de la ejecución es la siguiente:

Como se puede ver, la salida es la misma en ambos casos, la diferencia es que si quisiéramos añadir una puerta con cerradura de tipo “Reconocimiento_dactilar“, en el primer caso, tendríamos que crear un nuevo tipo de puerta que tuviera como atributo un objeto de tipo CerraduraDactilar y ya tendríamos tres objetos distintos cuya única diferencia es el tipo de un atributo.

En el segundo caso, usando DI, bastaría con crear el objeto CerraduraDactilar y pasarla como parámetro al constructor de ObjetoPuerta. Seguiríamos teniendo un solo ObjetoPuerta y solamente añadiríamos la nueva implementación de la cerradura.

Uno de los problemas que plantea el uso de interfaces es que a la hora de depurar visualmente el código no vemos de que tipo es el objeto que pasamos, ya que solo vemos su representación como interface, nada que haciendo Debug en nuestro IDE no se solucione.

Es cierto que podríamos haber creado un ObjetoPuerta genérico del que heredasen todos los demás objetosPuerta con sus atributos cerradura concretos, pero no resolveríamos en nada el problema de tener objetos iguales cuyas únicas diferencias son un atributo.

Alguien puede preguntarse la utilidad real de este patrón teniendo en cuenta que pudiera ser que tuviéramos un ObjetoPuerta que tuviera dos o más atributos o un ObjetoCerradura que tuviera algún atributo y volvería a presentarse el problema inicial, creo dos objetos de tipo CerraduraConAtributo y CerraduraSinAtributo o vuelvo a usar DI.

Pero aún usando DI, a la fuerza tendremos que instanciar los dos tipos de cerradura y pasar como parámetro al ObjetoPuerta la que nos convenga en el momento, tal y como hemos hecho con ObjetoCerraduraCodigo y ObjetoCerraduraLlave.

Para solventar todo esto existe la inversión de control (IoC) donde veremos como mediante la inyección de dependencias y la reflexión se irán creando las instancias de clases que necesitemos según el momento y necesidad trasladando todo el control fuera de la clase principal.

Enlaces|
¿Qué es la inyección de dependencias?
 

<O,_,O>

  • Pingback: Bitacoras.com()

  • Nico

    DE 10! Por fin lo entendi!

  • Mejor explicado no se puede. Ty! (:

  • Diana

    Siii se entiende

  • Darwin

    Muy bienexplicado