Inyección de Dependencias
La Inyección de Dependencias es un patrón de diseño que ha ido ganando , en la última década 1), mucha aceptación entre los programadores , especialmente en la comunidad Java.
La Inyección de Dependencias es parte de un concepto mas amplio llamado Inversión del control , aunque en mucha gente los suele utilizar como sinónimos.Para simplificar la explicación nosotros también vamos a tratarlos como cosas equivalentes aunque sea un concepto erróneo .
La Inyección de Dependencias ( o la Inversión del control) se basa en que, en vez de que una clase vaya a buscar los objetos que necesita llamando a métodos que se los proporcionan, se hace al reves, siendo estos últimos los que se asignan automáticamente al objeto.
Antes de ver el código Java vamos a poner un par de ejemplos cotidianos sobre el concepto de Inversión del control:
- En vez de ir a una oficina a que te hagan un seguro para el coche, que sea el agente de seguros el que viene a tu casa para hacerte el seguro.
- Cuando después de pasar una noche con una chica que acabas de conocer y que te ha gustado, le dices que la llamarás al día siguiente y ella te contesta, no te preocupes ya te llamaré yo.
- Si en vez de ir a tu al médico cuando estás enfermo , es el médico el que viene a tu casa.
Como podemos ver , los resultados son prácticamente lo mismo si hacemos las cosas de forma normal o invertimos la forma de hacerlo 2).
Veamos el siguiente código Java:
public class PruebaIoC { SessionFactory sessionFactory=HibernateUtil.getSessionFactory(); ProfesorDAO profesorDAO=new ProfesorDAOImplHibernate(); }
Hasta ahora, si nuestra clase PruebaIoC
necesitaba un objeto, se llamaba a un método que le proveía dicho objeto o simplemente se creaba con new
, tal y como vemos en las líneas anteriores.
Obviamente, la línea ProfesorDAO profesorDAO=new ProfesorDAOImplHibernate()
es bastante lamentable ya que estamos atando el código de PruebaIoC
a una implementación concreta del interfaz ProfesorDAO
. Éso se debe evitar a toda costa , aunque una solución es crear otra clase de factoría del interfaz ProfesorDAO
.
Ésto nos lleva a preguntarnos , ¿qué tiene de malo la llamada a getSessionFactory()
?
Pues que el código de PruebaIoC
está acoplado a la clase HibernateUtil
cuando realmente no la queremos para nada. Lo que PruebaIoC
necesita es un SessionFactory
y no debería saber nada sobre HibernateUtil
. HibernateUtil
podría ser subtituida por cualquier otra y no debería afectar nunca a PruebaIoC
ya que no la necesita.
¿Cómo lo solucionamos?
Pues con la Inyección de Dependencias. La clase quedará ahora de la siguiente manera:
public class PruebaIoC { SessionFactory sessionFactory; ProfesorDAO profesorDAO; }
Vemos cómo ahora sólo se declaran las 2 propiedades. El framework de Inyección de Dependencias que usemos, automáticamente asignará los valores a las 2 propiedades sin que la clase PruebaIoC
sepa de dónde han salido. Es decir, que hemos eliminado las dependencias a HibernateUtil
y hemos evitado incluir en el código la implementación concreta del interfaz ProfesorDAO
.