alt=A diagram of an archetypical dependency injection container for the .NET platform.|miniatura|La injecció de dependències s'utilitza sovint juntament amb marcs de treball especialitzats, coneguts com a "contenidors", per facilitar la composició de programes. En enginyeria de programari, la injecció de dependències és una tècnica de programació en què un objecte o funció rep altres objectes o funcions que requereix, en comptes de crear-los internament. La injecció de dependències té com a objectiu separar les preocupacions de construir objectes i utilitzar-los, donant lloc a programes poc acoblats. El patró garanteix que un objecte o funció que vulgui utilitzar un servei determinat no hagi de saber com construir aquests serveis. En canvi, el "client" receptor (objecte o funció) rep les seves dependències mitjançant codi extern (un "injector"), del qual no és conscient. La injecció de dependències fa explícites les dependències implícites i ajuda a resoldre els problemes següents: miniatura|PetManager s'injecta a PetController i PetRepository s'injecta a PetManager.

Com pot una classe ser independent de la creació dels objectes dels quals depèn? Com poden una aplicació i els objectes que utilitza admetre diferents configuracions?

La injecció de dependències s'utilitza sovint per mantenir el codi en línia amb el principi d'inversió de dependències.

En llenguatges amb tipatge estàtic, l'ús de la injecció de dependències significa que un client només ha de declarar les interfícies dels serveis que utilitza, en lloc de les seves implementacions concretes, cosa que facilita el canvi dels serveis que s'utilitzen en temps d'execució sense haver de recompilar.

Els frameworks d'aplicacions sovint combinen la injecció de dependències amb la inversió del control. Sota la inversió del control, el framework primer construeix un objecte (com ara un controlador) i després li passa el flux de control. Amb la injecció de dependències, el framework també instancia les dependències declarades per l'objecte de l'aplicació (sovint en els paràmetres del mètode constructor) i passa les dependències a l'objecte.

La injecció de dependències implementa la idea d'"invertir el control sobre les implementacions de les dependències", motiu pel qual certs frameworks de Java anomenen genèricament el concepte "inversió de control" (no s'ha de confondre amb la inversió del flux de control).

Rols La injecció de dependències implica quatre rols: serveis, clients, interfícies i injectors.

Serveis i clients Un servei és qualsevol classe que conté una funcionalitat útil. Al seu torn, un client és qualsevol classe que utilitza serveis. Els serveis que un client requereix són les dependències del client.

Qualsevol objecte pot ser un servei o un client; els noms només es refereixen al paper que juguen els objectes en una injecció. El mateix objecte pot ser fins i tot un client (utilitza serveis injectats) i un servei (s'injecta en altres objectes). En injectar-se, el servei passa a formar part de l'estat del client i està disponible per al seu ús.

Interfícies Els clients no haurien de saber com s'implementen les seves dependències, només els seus noms i l'API. Un servei que recupera correus electrònics, per exemple, pot utilitzar els protocols IMAP o POP3 entre bastidors, però aquest detall probablement és irrellevant per cridar codi que simplement vol que es recuperi un correu electrònic. En ignorar els detalls de la implementació, els clients no necessiten canviar quan ho fan les seves dependències.

Injectors L'injector, de vegades també anomenat muntador, contenidor, proveïdor o fàbrica, introdueix serveis al client.

La funció dels injectors és construir i connectar grafs d'objectes complexos, on els objectes poden ser tant clients com serveis. L'injector en si pot ser molts objectes treballant junts, però no ha de ser el client, ja que això crearia una dependència circular.

Com que la injecció de dependències separa com es construeixen els objectes de com s'utilitzen, sovint disminueix la importància de la paraula clau new que es troba a la majoria de llenguatges orientats a objectes. Com que el marc de treball s'encarrega de la creació de serveis, el programador tendeix a construir directament només objectes de valor que representen entitats del domini del programa (com ara un objecte Employee en una aplicació empresarial o un objecte Order en una aplicació de compres).

Analogia Com a analogia, els cotxes es poden considerar com a serveis que realitzen la tasca útil de transportar persones d'un lloc a un altre. Els motors dels cotxes poden requerir gasolina, dièsel o electricitat, però aquest detall no és important per al client —un passatger— a qui només li importa si pot portar-lo a la seva destinació.

Els cotxes presenten una interfície uniforme a través dels seus pedals, volants i altres controls. Per tant, el motor amb què es van "injectar" a la línia de fàbrica deixa de tenir importància i els conductors poden canviar entre qualsevol tipus de cotxe segons calgui.

Avantatges i desavantatges Avantatges A basic benefit of dependency injection is decreased coupling between classes and their dependencies.

En eliminar el coneixement d'un client sobre com s'implementen les seves dependències, els programes esdevenen més reutilitzables, provables i mantenibles.

Això també es tradueix en una major flexibilitat: un client pot actuar sobre qualsevol cosa que admeti la interfície intrínseca que el client espera.

Més generalment, la injecció de dependències redueix el codi repetitiu, ja que tota la creació de dependències la gestiona un component singular.

Finalment, la injecció de dependències permet el desenvolupament concurrent. Dos desenvolupadors poden desenvolupar classes de manera independent que s'utilitzen mútuament, mentre només necessiten conèixer la interfície a través de la qual es comunicaran les classes. Els complements sovint són desenvolupats per tercers que ni tan sols parlen amb els desenvolupadors del producte original.

Desavantatges Els crítics de la injecció de dependències argumenten que:

Crea clients que exigeixen detalls de configuració, cosa que pot ser complicada quan hi ha disponibles valors per defecte evidents. Fa que el codi sigui difícil de rastrejar perquè separa el comportament de la construcció. Normalment s'implementa amb reflexió o programació dinàmica, cosa que dificulta l'automatització de l'IDE. Normalment requereix més esforç de desenvolupament inicial. Fomenta la dependència d'un marc de treball.

Tipus d'injecció de dependències Hi ha diverses maneres en què un client pot rebre serveis injectats:

Injecció de constructors, on les dependències es proporcionen a través del constructor de classe d'un client. Injecció de mètodes, on les dependències es proporcionen a un mètode només quan cal per a una funcionalitat específica. Injecció de setter, on el client exposa un mètode de setter que accepta la dependència. Injecció d'interfície, on la interfície de la dependència proporciona un mètode d'injector que injectarà la dependència a qualsevol client que se li passi.

En alguns marcs de treball, els clients no necessiten acceptar activament la injecció de dependències. A Java, per exemple, la reflexió pot fer públics els atributs privats durant les proves i injectar serveis directament.

Referències

Categoria:Programari Categoria:Informàtica teòrica