függőségi injektálás nélkülszerkesztés

a következő Java példában az Ügyfélosztály tartalmaz egy Service member változót, amelyet az ügyfél konstruktor inicializál. Az ügyfél ellenőrzi, hogy a szolgáltatás mely végrehajtását használják, és ellenőrzi annak felépítését. Ebben a helyzetben, az ügyfél azt mondta, hogy egy kemény kódolt függőség ExampleService.

// An example without dependency injectionpublic class Client { // Internal reference to the service used by this client private ExampleService service; // Constructor Client() { // Specify a specific implementation in the constructor instead of using dependency injection service = new ExampleService(); } // Method within this client that uses the services public String greet() { return "Hello " + service.getName(); }}

a függőségi befecskendezés egy alternatív módszer a tagváltozó inicializálására, nem pedig egy szolgáltatási objektum kifejezett létrehozására a fentiek szerint., Ezt a példát az alábbi alszakaszokban leírt és bemutatott különböző technikák segítségével állíthatjuk be.

a dependency injectionEdit

típusai az ügyfélobjektumnak legalább három módja van arra, hogy hivatkozást kapjon egy külső modulra:

constructor injection a függőségek az ügyfél osztály konstruktorán keresztül kerülnek megadásra. setter injection az ügyfél kiteszi a szetter módszer, hogy az injektor használja, hogy adja be a függőség. interface injection a dependency interfésze egy injektor módszert biztosít, amely a függőséget minden átadott ügyfélbe befecskendezi., Az ügyfeleknek végre kell hajtaniuk egy olyan felületet, amely kiteszi a függőséget elfogadó szetter módszert.

Egyéb típusokszerkesztés

lehetséges, hogy a DI keretrendszerek más típusú injekciókat is tartalmazzanak a fent bemutatottakon túl.a

tesztelési keretrendszerek más típusokat is használhatnak. Néhány modern tesztelési keretrendszer még azt sem követeli meg, hogy az ügyfelek aktívan elfogadják a függőségi befecskendezést, így a régi kód tesztelhetővé válik. Különösen a Java nyelvben lehetséges a reflexió használata, hogy a magánjellegű attribútumok nyilvánosságra kerüljenek a tesztelés során, így hozzárendeléssel fogadják el az injekciókat.,

egyes ellenőrzési kísérletek nem biztosítják a függőség teljes eltávolítását, hanem egyszerűen helyettesítik a függőség egyik formáját a másikra. Alapszabályként, ha egy programozó csak az ügyfélkódot tudja megnézni, és megmondja, hogy milyen keretrendszert használ, akkor az ügyfél nehezen kódolt függést mutat a keretrendszertől.

Constructor injectionEdit

Ez a módszer megköveteli az ügyféltől, hogy adjon meg egy paramétert egy konstruktorban a függőséghez.

setter injectionEdit

Ez a módszer megköveteli, hogy az ügyfél egy szetter módszert biztosítson a függőséghez.,

interface injectionEdit

Ez egyszerűen az ügyfél, aki szerepfelületet tesz közzé az ügyfél függőségeinek beállítási módszereihez. Használható annak megállapítására, hogy az injektornak hogyan kell beszélnie az ügyféllel a függőségek befecskendezésekor.

// Service setter interface.public interface ServiceSetter { public void setService(Service service);}// Client classpublic class Client implements ServiceSetter { // Internal reference to the service used by this client. private Service service; // Set the service that this client is to use. @Override public void setService(Service service) { this.service = service; }}

Constructor injection comparisonEdit

előnyös, ha az összes függőséget lehet kialakítani az első, mert lehet használni, hogy az ügyfél objektum mindig érvényes állapotban, szemben azzal, hogy néhány függőségi referenciák null (nem lehet beállítani)., Önmagában azonban hiányzik a rugalmasság ahhoz, hogy függőségei később megváltozzanak. Ez lehet az első lépés az ügyfél megváltoztathatatlansága felé,ezért biztonságos a szál.

Setter injection comparisonEdit

megköveteli, hogy az ügyfél minden függőséghez szetter módszert biztosítson. Ez lehetővé teszi a függőségi referenciák állapotának bármikor történő manipulálását. Ez rugalmasságot biztosít, de ha egynél több függőséget kell beadni, az ügyfél számára nehéz biztosítani, hogy minden függőséget befecskendezzenek, mielőtt az ügyfél felhasználásra kerülne.,

mivel ezek az injekciók önállóan történnek, nem lehet megmondani, mikor fejeződik be az injektor az ügyfél bekötése. A függőség lehet hagyni null egyszerűen az injektor nem hívja a szetter. Ez arra kényszeríti az ellenőrzést, hogy az injekció befejeződött, amikor az ügyfél össze, amikor azt használják.

Interface injection comparisonEdit

Az interface injection előnye, hogy a függőségek teljesen tudatlanok lehetnek ügyfeleikről, mégis hivatkozást kaphatnak egy új ügyfélre, és ennek segítségével visszaküldhetik az ügyfélre., Ily módon a függőségek injektorokká válnak. A kulcs az, hogy az injekciós módszert (amely csak egy klasszikus szetter módszer lehet) egy interfészen keresztül biztosítják.

egy assembler még mindig szükség van, hogy vezessenek be az ügyfél és a függőségek. Az assembler egy hivatkozás, hogy az ügyfél, öntött, hogy a szetter felület, amely meghatározza, hogy a függőség, illetve adja, hogy ez a függőség tárgy, amely az lenne, fordulj át a referencia-hogy-egyéni vissza az ügyfél.,

ahhoz, hogy az interfészinjekció értéke legyen, a függőségnek valamit meg kell tennie, amellett, hogy egyszerűen visszaadja a hivatkozást önmagára. Ez lehet működő, mint egy gyári vagy al-assembler megoldani más függőségek, így absztrakció néhány részletet a fő assembler. Lehet referencia-számlálás, hogy a függőség tudja, hány ügyfél használja. Ha a függőség fenntartja az ügyfelek gyűjteményét, akkor később mindegyiket más példával is beadhatja.,

Assembling examplesEdit

a függőségi befecskendezés végrehajtásának egyik módja a kézzel történő kézi összeszerelés.

a fenti példa kézzel szerkeszti az objektumgráfot, majd egy ponton meghívja a működését. Fontos megjegyezni, hogy ez az injektor nem tiszta. Az általa létrehozott objektumok egyikét használja. Ez egy tisztán építési-csak kapcsolatot ExampleService de keveri építése és használata ügyfél. Ez nem lehet gyakori. Ez azonban elkerülhetetlen., Csakúgy, mint az objektumorientált szoftvernek szüksége van egy nem objektumorientált statikus módszerre, mint például a main() az induláshoz, egy függőségi injektált objektumgráfnak legalább egy (lehetőleg csak egy) belépési pontra van szüksége az egész elindításához.

a fő módszer kézi felépítése nem lehet ilyen egyenesen előre, és magában foglalhatja az építők, gyárak vagy más építési minták hívását is. Ez meglehetősen fejlett és elvont lehet., A sor átkerül a kézi függőségi befecskendezéstől a framework dependency injection-ig, miután az építőkód már nem egyedi az alkalmazáshoz, hanem univerzális.

az olyan keretrendszerek, mint a Spring, ugyanazokat az objektumokat építhetik fel, majd összekapcsolhatják őket, mielőtt visszatérnének a kliensre való hivatkozáshoz. A konkrét példák minden említésea szolgáltatás áthelyezhető a kódról a konfigurációs adatokra.

az olyan keretrendszerek, mint a Spring, lehetővé teszik az összeszerelési adatok külső megjelenítését a konfigurációs fájlokban.Ez a kód (fent) objektumokat épít ki, és a babok szerint összeköti őket.xml (lent)., Például a szolgáltatás még mindig épül, annak ellenére, hogy csak az alábbiakban említjük. Egy hosszú és összetett objektumgráf így definiálható, a kódban csak a belépési pont metódus szerepel, amely ebben az esetben a gráf().

a fenti példában az ügyfélnek és a szolgáltatásnak tavasszal nem kellett semmilyen változtatást végrehajtania. Ezek maradhatnak egyszerű POJOs. Ez azt mutatja, hogy a tavasz hogyan tudja összekapcsolni azokat a szolgáltatásokat és ügyfeleket, amelyek teljesen tudatlanok a létezéséről. Ezt nem lehetett mondani, ha tavaszi megjegyzéseket adtak az osztályokhoz., Azzal, hogy a Tavaszspecifikus kommentárokat és hívásokat sok osztály között elterjesztik, a rendszer csak lazán függ a tavasztól. Ez akkor lehet fontos, ha a rendszer túl akarja élni a tavaszt.

a POJOs tisztaságának megválasztása nem jár költség nélkül. Ahelyett, hogy a komplex konfigurációs fájlok fejlesztésére és karbantartására fordítanánk a fáradságot, egyszerűen csak jegyzetekkel jelölhetjük meg az osztályokat, és hagyhatjuk, hogy a Spring végezze a munka többi részét. A függőségek megoldása egyszerű lehet, ha olyan egyezményt követnek, mint például a típus vagy a név szerinti illesztés. Ez választja egyezmény felett konfiguráció., Az is vitatható, hogy amikor írd újra, hogy egy másik keret eltávolítása keret adott kommentárok lenne egy jelentéktelen része a feladat, sok injekció kommentárok most szabványosított.

@Componentpublic class ExampleService { public String getName() { return "World!"; }}

Assembly comparisonEdit

a különböző injektor implementációk (gyárak, szerviz lokátorok és függőségi befecskendező konténerek) nem különböznek egymástól a függőségi befecskendezés tekintetében. Ami a különbséget teszi, az az, hogy hol szabad használni őket., A hívások áthelyezése egy gyárba vagy egy szervizkeresőbe az ügyfélből, majd a fő-és hirtelen főbe, meglehetősen jó függőségi befecskendező tartályt eredményez.

az injektor minden tudásának elmozdításával egy tiszta, a külvilág ismereteitől mentes ügyfél marad hátra. Azonban minden olyan objektum, amely más objektumokat használ, kliensnek tekinthető. A fő objektumot tartalmazó objektum sem kivétel. Ez a fő objektum nem használ függőségi injekciót. Valójában a szolgáltatáskereső mintát használja. Ezt nem lehet elkerülni, mert a szolgáltatási megvalósítások kiválasztását valahol meg kell tenni.,

a függőségek konfigurációs fájlokba történő kiszervezése nem változtatja meg ezt a tényt. Mi teszi ezt a valóságot része egy jó design, hogy a szolgáltatás lokátor nem terjedt el az egész kód bázis. Alkalmazásonként egy helyre korlátozódik. Így a kódbázis többi része szabadon használhatja a dependency injection-t, hogy tiszta ügyfeleket hozzon létre.

Dependency Injection PatternEdit

a példák eddig túlságosan egyszerű példák voltak egy karakterlánc felépítésére., A függőségi befecskendezési minta azonban a leghasznosabb egy objektumgráf felépítésekor, ahol az objektumok üzeneteken keresztül kommunikálnak. Tárgyak épített fő tart az élet a program. A tipikus minta a grafikon felépítése, majd egy objektumon egy módszer meghívása, hogy a vezérlőáramot az objektumgráfba küldje. Csakúgy, mint a statikus kód belépési pontja, ez az egyik módszer az alkalmazások belépési pontja nem statikus kód.,

AngularJS exampleEdit

az AngularJS keretrendszerben csak háromféleképpen lehet egy összetevő (objektum vagy funkció) közvetlenül hozzáférni függőségeihez:

  1. az összetevő létrehozhatja a függőséget, általában a new operátor használatával.
  2. az összetevő egy globális változóra hivatkozva fel tudja keresni a függőséget.
  3. az összetevő lehet a függőség át, ahol szükség van rá.

a függőségek létrehozásának vagy keresésének első két lehetősége nem optimális, mert keményen kódolják az összetevőtől való függőséget., Ez megnehezíti, ha nem lehetetlen, a függőségek módosítását. Ez különösen problematikus a tesztekben, ahol gyakran kívánatos a tesztszigetelés álfüggőségeinek biztosítása.

a harmadik lehetőség a leginkább életképes, mivel eltávolítja a függőséget az összetevőből. A függőséget egyszerűen átadják az összetevőnek.

a fenti példában a SomeClass nem foglalkozik a greeter függőség létrehozásával vagy lokalizálásával, egyszerűen átadja a greetert, amikor instantiated.,

Ez kívánatos,de felelősséget vállal a SomeClasskódot felépítő függőség megszerzéséért.

a függőség létrehozásának felelősségének kezeléséhez minden AngularJS alkalmazásnak van egy injektora. A befecskendező egy szerviz lokátor, amely felelős a függőségek felépítéséért és megjelenítéséért.

íme egy példa az injektor szolgáltatás használatára:

Hozzon létre egy új injektort, amely a myModule modulban meghatározott összetevőket képes biztosítani, és kérje a greeter szolgáltatást az injektortól., (Ez általában automatikusan történik az AngularJS bootstrap).

var injector = angular.injector();var greeter = injector.get('greeter');

a függőségek kérése megoldja a kemény kódolás kérdését, de ez azt is jelenti, hogy az injektort az alkalmazás során át kell adni. Az injektor átadása megsérti Demeter törvényét., Ennek orvoslására használjuk a deklaratív jelölést a HTML sablonok, viszont a felelőssége összetevő létrehozása a injektor, mint ez a példa:

<div ng-controller="MyController"> <button ng-click="sayHello()">Hello</button></div>
function MyController($scope, greeter) { $scope.sayHello = function() { greeter.greet('Hello World'); };}

Ha AngularJS összeállítja a HTML, a folyamatok a ng-controller irányelv, ami viszont kéri a injektor, hogy hozzon létre egy példányát az adatkezelő, valamint a függőségek.

injector.instantiate(MyController);

Ez mind a színfalak mögött történik., Mivel ang-controller elhalasztja az injektort az osztály példányosításához, kielégíti aMyController összes függőségét anélkül, hogy a vezérlő valaha is tudott volna az injektorról. Az alkalmazás kódja egyszerűen kijelenti a szükséges függőségeket, anélkül, hogy foglalkoznia kellene az injektorral. Ez a beállítás nem szegi meg Demeter törvényét.

C # Edit

példa a konstruktor injekció, szetter injekció és interfész injekció C #

Articles

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük