inyección de dependencias

La inyección de dependencias en Java

inyección de dependenciasEn el post de hoy voy a dejar unos apuntes que me parecen muy fáciles de entender con respecto a la inyección de dependencias en Java. Estas inyecciones son un  patrón de diseño que deriba en un patrón más genérico llamado Inversión de Control. La inyección de dependencias hace uso de la modularidad y la reutilización posible en este lenguaje, para utilizarlas siempre habrá que tener en cuenta si la aplicaciones que desarrollamos va a tener disponible una mayor funcionalidad

Los código que voy  a utilizar para ejemplificar este concepto no es propio, lo encontré buscando un poco por google. En el se 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 la inyección de dependencias:

Ejemplo de inyección de dependecias en Java

Start.java



Esto es lo que se ha hecho toda la vida, 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”.

ObjetoPuertaLlave.java:

ObjetoCerraduraLlave.java:

ObjetoPuertaCodigo.java:

ObjetoCerraduraCodigo.java:

La salida por consola de la ejecución es la siguiente vendría siendo algo como esto:

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

ObjetoPuerta.java:

Esta clase puerta es más genérica que la anterior y consta de un atributo que es una interface. Esto es a groso modo la inyección de dependencias, en la que en lugar de invocar instancias nuevas de objetos desde la propia clase, se invocan desde fuera de esta. Estas instancias serán 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 habría 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. Vamos, que esta no es la mejor manera de optimizar un poco el código.

En el segundo caso, usando inyección de dependencias, bastaría con crear el objeto CerraduraDactilar y pasarla como parámetro al constructor de ObjetoPuerta. Tendríamos un solo ObjetoPuerta y solamente añadiríamos la nueva implementación de la cerradura, ahorrándonos una cuantas líneas de código.

Uno de los problemas que plantea el uso de interfaces viene a la hora de depurar visualmente el código ya que no vemos de que tipo es el objeto que pasamos pues solo vemos su representación como interface. Esto puede ser un problema, pero para eso se inventaron los Debug del IDE de turno.

Alguna gente a estas alturas podría pensar que  podríamos haber creado un ObjetoPuerta genérico del que heredasen todos los demás objetosPuerta, con sus atributos cerradura concretos, pero no esto no resolvería el problema de tener objetos iguales cuyas únicas diferencias son un atributo. Entonces como que descartaré esa opción.

Alguien puede preguntarse la utilidad real de este patrón teniendo en cuenta que podríamos tener un ObjetoPuerta con dos o más atributos, o un ObjetoCerradura que tuviera algún atributo, pero volvería a presentarse el problema inicial, ¿creo dos objetos de tipo CerraduraConAtributo y CerraduraSinAtributo o vuelvo a usar inyección de dependecias?.

Pero aún usando la inyección de dependencias 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 donde 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.

Más info

Deja un comentario