Függőség-injekció

Az oldal jelenlegi verzióját még nem ellenőrizték tapasztalt közreműködők, és jelentősen eltérhet a 2019. november 14-én felülvizsgált verziótól ; az ellenőrzések 16 szerkesztést igényelnek .

A függőségi befecskendezés (DI ) az a folyamat, amely külső függőséget biztosít egy szoftverkomponenshez .  Ez a „ vezérlés megfordítása ” ( angolul Inversion of control, IoC ) egy speciális formája, amikor a függőségkezelésre alkalmazzák. Az egyetlen felelősség elvének teljes mértékben megfelelve az objektum a szükséges függőségek kiépítését egy külsőre bízza, speciálisan ehhez az általános mechanizmushoz [1] .  

Valós függőségi injekció

A "függőségi injektálás" minta használatakor az objektum passzív, és egyáltalán nem tesz lépéseket a függőségek meghatározására, hanem beállítókat biztosít ehhez , és/vagy elfogad argumentumokat a konstruktorában, amelyeken keresztül a függőségek injektálódnak [1] .

Hogyan működik

A függőségi injekció keretrendszerének működését az alábbiakban ismertetjük. Az alkalmazás, a tervezéstől függetlenül, a keretrendszer által biztosított IoC tárolóban fut . A programban lévő objektumok egy része továbbra is a programozási nyelv megszokott módon jön létre, néhányat a konténer hozza létre a számára biztosított konfiguráció alapján.

Megállapodás szerint, ha egy objektumnak hozzá kell férnie egy adott szolgáltatáshoz , az objektum átveszi a felelősséget a szolgáltatás eléréséért: vagy közvetlen hivatkozást kap a szolgáltatás helyére, vagy egy jól ismert "szolgáltatáskeresőhöz " megy, és hivatkozást kér egy adott szolgáltatástípus megvalósítására. A függőségi injektálás használatával egy objektum egyszerűen felfed egy tulajdonságot, amely képes a kívánt szolgáltatástípus hivatkozását tárolni; objektum létrehozásakor pedig a környezeti eszközök segítségével ebbe a tulajdonságba (mezőbe) automatikusan beszúrásra kerül egy hivatkozás a kívánt szolgáltatástípus megvalósítására.

A függőségi befecskendezés rugalmasabb, mert egyszerűbbé válik egy adott típusú szolgáltatás alternatív megvalósításainak létrehozása, majd megadhatja, hogy melyik megvalósítást kell használni például egy konfigurációs fájlban anélkül, hogy módosítaná az adott szolgáltatást használó objektumokat. Ez különösen az egységteszteknél hasznos, mert nagyon egyszerű a szolgáltatás " csonk " megvalósítását beilleszteni a tesztelt objektumba.

Másrészt a függőségi injekció túlzott használata bonyolultabbá és nehezebben karbantarthatóvá teheti az alkalmazásokat: mivel egy program viselkedésének megértéséhez a programozónak nem csak a forráskódot, hanem a konfigurációt is meg kell néznie, és a konfiguráció általában láthatatlan az IDE számára , amely támogatja a hivatkozáselemzést és az újrafaktorálást , hacsak nincs kifejezetten megadva a függőségi beillesztési keretrendszerek támogatására.

Kódpéldák

A függőségi injekció használatakor általában létezik egy konfigurációs mechanizmus vagy architektúra, amely a céloktól függően meghatározza az egyik vagy másik megvalósítás kiválasztásának megfelelőségét.

Példák különböző nyelveken

PHP kód példa

<?php /** * Adatbázis konfigurációs osztály */ osztályú DbConfiguration { privát $host ; privát $port ; privát $felhasználónév ; privát $jelszó ; public function __construct ( string $host , int $port , string $username , string $password ) { // a Di egész pontja az alábbi sorokban van $this -> host = $host ; $this -> port = $port ; $this -> username = $felhasználónév ; $this -> jelszó = $jelszó ; } nyilvános függvény getHost () { return $this -> host ; } nyilvános függvény getPort () { return $this -> port ; } nyilvános függvény getUsername () { return $this -> username ; } nyilvános függvény getPassword () { return $this -> jelszó ; } } /** * Adatbázis kapcsolati osztály */ osztályú DbConnection { privát $konfiguráció ; nyilvános függvény __construct ( DbConfiguration $config ) { // a Di teljes lényege az alábbi sorban van $this -> konfiguráció = $config ; } nyilvános függvény getDsn () { // Megjegyzés: ez nem igazi dsn, a valódi dsn határolók mások return sprintf ( '%s:%s@%s:%d' , $this -> konfiguráció -> getUsername (), $this -> konfiguráció -> getPassword (), $this -> konfiguráció -> getHost (), $this -> konfiguráció -> getPort () ); } } // hozzon létre egy adatbázis-konfigurációs objektumot a paraméterek konstruktornak való átadásával $config = new DbConfiguration ( 'localhost' , 3306 , 'felhasználónév' , 'jelszó' ); // adatbázis-kapcsolati objektum létrehozása a konfigurációs objektum konstruktornak való elküldésével // A Di használatával a kód lazán összekapcsolódik $kapcsolat = new DbConnection ( $config );

Java kód példa

public interface ICar { public float getSpeed ​​(); public void setPedalPressure ( végső lebegés PEDAL_PRESSURE ); } nyilvános interfész IEngine { public float getEngineRotation (); public void setFuelConsumptionRate ( végső lebegő FUEL_FLOW ); } A függőségi injekció használata nélkül public class DefaultEngineImpl implementálja az IEngine-t { private float engineRotation = 0 ; public float getEngineRotation () { return engineRotation ; } public void setFuelConsumptionRate ( végső lebegő FUEL_FLOW ) { engineRotation = ... ; } } public class DefaultCarImpl implements ICar { private IEngine engine = new DefaultEngineImpl (); public float getSpeed ​​() { return engine . getEngineRotation () * ... ; } public void setPedalPressure ( végső float PEDAL_PRESSURE ) { motor . setFuelConsumptionRate ( ... ); } } public class MyApplication { public static void main ( String [] args ) { DefaultCarImpl car = new DefaultCarImpl (); autó . setPedalPressure ( 5 ); úszósebesség = autó . _ getSpeed ​​(); Rendszer . ki . println ( "Az autó sebessége" + sebesség ); } } Kézi függőségi injekció public class DefaultCarImpl implementálja az ICar { private IEengine engine ; public DefaultCarImpl ( végső IEngine engineImpl ) { motor = engineImpl ; } public float getSpeed ​​() { return engine . getEngineRotation () * ... ; } public void setPedalPressure ( végső float PEDAL_PRESSURE ) { motor . setFuelConsumptionRate ( ... ); } } public class CarFactory { public static ICar buildCar () { return new DefaultCarImpl ( new DefaultEngineImpl ()); } } public class MyApplication { public static void main ( String [ ] args ) { ICar car = CarFactory . buildCar (); autó . setPedalPressure ( 5 ); úszósebesség = autó . _ getSpeed ​​(); Rendszer . ki . println ( "Az autó sebessége" + sebesség ); } } Függőség-injekció egy keretrendszerrel <service-point id= "CarBuilderService" > <invoke-factory> <construct class= "Car" > <service> DefaultCarImpl </service> <service> DefaultEngineImpl </service> </construct> </invoke-factory> < /service-point> /** Implicit megvalósítás **/ public class MyApplication { public static void main ( String [ ] args ) { Service service = ( Service ) DependencyManager . get ( "CarBuilderService" ); ICar autó = ( ICar ) szerviz . getService ( Autó . osztály ); autó . setPedalPressure ( 5 ); úszósebesség = autó . _ getSpeed ​​(); Rendszer . ki . println ( "Az autó sebessége" + sebesség ); } }

Lásd még

Jegyzetek

  1. 2008. Márton 12 .

Irodalom

Linkek