![]()
A függőség-injektálás egy szoftverfejlesztési technika, ahol az objektumok átadják a többi objektum példányát, amelyektől függenek. Ahelyett, hogy maguk a külső függőségek beolvasására törekednének, az objektumoknak közvetlenül meg kell kapniuk mindent, ami a működésükhöz szükséges.
Egy alap példa
A „függőségi injekció” kifejezés és meghatározása összetettnek tűnhet. A gyakorlatban ez egy egyszerű fogalom. Nézzünk meg egy alapobjektum létrehozásának két megközelítését. Itt PHP-t használunk, de a fogalmak minden objektum-orientált kódalapra vonatkoznak.
Függőségi injekció nélkül
class UserCreator { protected Mailer $Mailer; public function __construct() { $this -> Mailer = new Mailer(); } public function create(string username, string $email) : void { $this -> Mailer -> send($email, "Your account", "Welcome."); } }
Függőségi injekcióval
class UserCreator { protected Mailer $Mailer; public function __construct(Mailer $mailer) { $this -> Mailer = $Mailer; } public function create(string $username, string $email) : void { $this -> Mailer -> send($email, "Your account", "Welcome."); } }
A különbség finom, de jelentős. Mindkét osztálynak van egy függőség rajta Mailer példa. Az első osztály megalkotja a sajátját Mailer, míg a második a Mailer amelyet a külvilág nyújt. A Mailer függőség volt befecskendezték az osztályba.
A függőségi injekció előnyei
A függőség-injektálás fő előnye az osztályok és függőségeik szétválasztása, amelyet ez nyújt. A függőségi injekció a a vezérlés inverziója – ahelyett, hogy az osztályok kontrollálnák saját függőségüket, a külső környezetük által biztosított példányokkal dolgoznak.
Pontosabban fogalmazva: a függőségek beadása leegyszerűsíti a jövőben ezeknek a függőségeknek a megváltoztatását. Egy igazi kódbázisban Mailer a fenti példánkban valószínűleg interfész lenne olyan megvalósításokkal, mint SendmailMailer, SendGridMailer és FakeMailer.
Az első példát véve, ha az osztályok közvetlenül konstruálják az egyiket Mailer példányok többletmunkát eredményeznek, ha ezt cserélnie kell Mailer végrehajtás. A függőségi injekció segítségével beírhatja a célzást Mailer interfész bármilyen kompatibilis megvalósítás elfogadásához. Az alkalmazandó megvalósítást a külvilág határozza meg.
Leggyakrabban függőségi injekciót fog használni az a-val együtt függőségi injekciós tartály. A konténerek általában integrálódnak az Ön által használt alkalmazás keretrendszerbe. Automatikusan megoldják és befecskendezik az osztályfüggőségeket.
Konténert kér a UserCreator előbb elkészítené a Mailer példa. Ezt továbbadnák a UserCreator konstruktor paraméterén keresztül. A konténert „bekötjük”, hogy meghatározzuk azt a megvalósítást, amelyet egy felület tipegnyomásakor használunk. Ebben a modellben az aktív megváltoztatása Mailer a teljes kódalapon csak a konténer újbóli bekötését igényli. Ez lehet egy kódsor a konténer konfigurációjában.
A tesztelésre gyakorolt hatások
A függőségi injekció megkönnyíti a függőségek kigúnyolását a tesztelés során. Mivel a függőségek kívülről származnak az osztályhoz, hamis megvalósítást biztosíthat az egység tesztjein:
class FakeMailer implements Mailer { public function send(string $to, string $subject, string $body) : void { return; } }
A teszteléskor nem kell üdvözlő e-mailt küldeni UserCreator. Mindazonáltal elkerülhetetlen lenne az első példában, ahol UserCreator mindig élőben konstruálja a sajátját Mailer. A függőségi injekcióval egy speciálisat nyújthatunk Mailer amely kielégíti az interfész szerződését, de kiküszöböli a mellékhatásokat.
Laza tengelykapcsoló
A függőség-injektálás nem a függőségek teljes kiküszöböléséről szól – mindig ott lesznek, de lazán össze kell kapcsolni őket. Gondoljon a függőségre, mint valamire, amely egy bizonyos ideig kapcsolódik, és nem egy tartósan ragasztott lámpatesthez.
Az első példában látható szoros összekapcsolás rugalmatlan kódot eredményez, amelyet nehéz áthelyezni. A függőségek átláthatatlanná válnak a külső szemlélőkkel, például a tesztfutókkal szemben. Az osztályodba átadott tipeginting interfészek a lehető legszabadabban kapcsolják össze függőségeidet.
Egységes felelősség elv
A függőségi injekció utolsó előnye, hogy képes betartani az Egyetlen felelősség elve. Ez kimondja, hogy minden osztálynak felelősnek kell lennie a kódbázis egyetlen önálló funkcionalitási egységéért.
Injekció nélkül az osztályok nemcsak funkcionalitást nyújtanak, hanem saját függőségüket is felépítik. Ez megköveteli, hogy minden osztály részletes ismeretekkel rendelkezzen más alrendszerek követelményeiről. Injekcióval az osztály ismeretei a külvilágról csak azokra a szerződésekre korlátozódnak, amelyeket az általa függő interfészek biztosítanak.
Következtetés
A függőség-injektálás megkönnyíti az objektum-orientált kódbázisok fenntartását. A saját függőségüket felépítő osztályok általában a kódszag. Végül szorosan kapcsolódnak a környezetükhöz, és trükkös a tesztelésük.
A függőségek kihasználása az őket használó osztályokból megfordítja az irányítást, és erőteljesebben szétválasztja az aggályokat. Ezt úgy gondolhatja, mint a keményen kódolt állandók eltávolítását: soha nem írna adatbázis-séma nevet a forrásába, mivel annak egy konfigurációs fájlban kell lennie.
A Mailer konfigurációs részlet is. UserCreator nem foglalkozhat a levelező rendszer felállításával. Valószínű, hogy újra szeretné használni ugyanazt a rendszert máshol a kódalapjában. A konfiguráció gyakrabban változik, mint a kód; valószínűleg módosítani kívánja a levelek küldésének módját, még jóval azelőtt, hogy módosítaná az üzleti követelményt, miszerint az e-mail küldésre kerül, amikor a felhasználó regisztrál.
Összefoglalva: a függőség-injektálás arra ösztönzi az összetevőket, hogy kérjék el a szükséges funkcionalitást, ahelyett, hogy darabonként, eseti alapon ragadnák meg. Az alkalmazásszintű példányok konténeren keresztüli huzalozása feltárja annak függőségét, hogy milyenek: a konfiguráció részletei, amelyek változhatnak. Kódolja be az osztályait, hogy elfogadja a környezettől származó absztrakciókat, a belsőépítésű konkrét megvalósítások helyett.
