El patró d’injecció de dependència sempre ha estat un dels conceptes que costa entendre en el món de el desenvolupament de programari sobretot a la gent que aquesta començant . Per a què serveix aquest patró de disseny i quin és el seu feu servir? Normalment quan nosaltres programem en el dia a dia amb la programació orientada a objecte ens trobem construint objectes i relacionant objectes utilitzant dependències.
per exemple podem tenir un programa principal que usi un senzill servei d’impressió per imprimir un document.
package com.arquitecturajava;public class ServicioImpresion {public void imprimir() {System.out.println("enviando el documento a imprimir");System.out.println("imprimiendo el documento en formato pdf");}}
Fem servir un programa main i imprimim:
package com.arquitecturajava;public class Principal {public static void main(String args) {ServicioImpresion miServicio= new ServicioImpresion();miServicio.imprimir();}}
Fins aquí no té res d’especial i veurem imprès el resultat a la consola:
Inyeccion de Dependència
No obstant això el més lògic és que aquest programa divideixi una mica més les seves responsabilitats i aquest compost de diversos serveis alguna cosa com el següent:
Fins aquí tot és bastant raonable i el que aconseguim és que el nostre servei d’impressió depengui d’altres serveis i les responsabilitats quedin més clares. Acabem de generar dependències a el Servei d’impressió. El codi seria alguna cosa com el següent.
public class ServicioImpresion {ServicioEnvio servicioA;ServicioPDF servicioB; public ServicioImpresion() {this.servicioA= new ServicioEnvio();this.servicioB= new ServicioPDF();}public void imprimir() {servicioA.enviar();servicioB.pdf();}}
public class ServicioEnvio {public void enviar() {System.out.println("enviando el documento a imprimir");}}
public class ServicioPDF {public void pdf() {System.out.println("imprimiendo el documento en formato pdf");}}
el resultat a la consola serà el mateix sol que hem dividit millor.
Es pot realitzar la mateixa operació injectant les dependències a l’ServicioImpresión i que no sigui ell el que hagi de definir-les al constructor.
Aquest sembla en principi un canvi sense importància , el codi quedaria:
package com.arquitecturajava.parte3;public class ServicioImpresion {ServicioEnvio servicioA;ServicioPDF servicioB;public ServicioImpresion(ServicioEnvio servicioA,ServicioPDF servicioB) {this.servicioA= servicioA;this.servicioB= servicioB;}public void imprimir() {servicioA.enviar();servicioB.pdf();}}
public class Principal {public static void main(String args) { ServicioImpresion miServicio= new ServicioImpresion(new ServicioEnvio(),new ServicioPDF());miServicio.imprimir();}}
el resultat segueix sent el mateix. Acabem d’injectar les dependències al servei des del nostre programa main. Quins avantatges aporta això? . La realitat és que en principi sembla que cap. Però hi ha una cosa que ha canviat ja no és el mateix servei el responsable de definir les seves dependències sinó que ho és el programa principal. Això obre les portes a la extensibilitat. És a dir ¿tenim nosaltres sempre que injectar les mateixes dependències a el servei ?. La resposta sembla òbvia … clar que sí estan ja definides. No obstant això la resposta és NO, nosaltres podem canviar el tipus de dependència que injectem, simplement estenent una de les nostres classes i canviant el comportament, anem a veure-ho.
public class ServicioEnvioAspecto extends ServicioEnvio {@Overridepublic void enviar() {System.out.println("haciendo log del correo que vamos a enviar");super.enviar();}}
Acabem de crear una classe que estén ServicioEnvio i afegeix una funcionalitat addicional de log que fa un “log” de l’correu que vam enviar. Ara és tan senzill com dir-li a el programa principal que quan injecti la dependència no injecti el ServicioEnvio sinó el ServicioEnvioAspecto d’aquesta manera haurem canviat el comportament de forma considerable.
public class Principal {public static void main(String args) {ServicioImpresion miServicio= new ServicioImpresion(new ServicioEnvioAspecto(),new ServicioPDF());miServicio.imprimir();}}
el resultat a la consola serà:
Acabem de modificar el comportament del nostre programa de forma significativa gràcies a l’ús de l’concepte d’injecció de dependència.
La injecció de dependència ens permet injectar altres classes i afegir funcionalitat transversal a mida. Aquest patró de disseny és el que obre la porta a frameworks com Spring utilitzant el concepte d’injecció de dependència d’una forma més avançada. En aquests framework els aspectes que s’afegeixen a les nostres classes són múltiples i la complexitat alta.
la importància de el patró d’injecció de dependència és avui clau en la majoria dels frameworks.
Altres articles relacionats
- Spring @Qualifier utilitzant @Autowired
- Spring @import, organitzant Spring framework
- Java 8 Factory Pattern i la seva implementació
Articles externs
- Dependency Inyection