Dependency Injection

Pagina: 1
Acties:
  • 872 views sinds 30-01-2008
  • Reageer

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 10:58

alienfruit

the alien you never expected

Topicstarter
Ik hoor steeds vaker de term Depency Injection om bepaalde problemen mee op te lossen. Nu heb ik al wat over het onderwerp gelezen, maar ik snap het eerlijk gezegt niet helemaal. Daarom dit topic omdat ik graag wat Nederlandse uitleg over dit ontwerp zoek. Wat ik tot nu heb begrepen is dat het te vergelijken is met de Service Locator J2EE pattern.

Nu heb je verschillende vormen van depency injection waaronder interface injection, en Constructor Injection. Volgens mij gebruik ik nu vaak de interface injection vorm mijn code, waarbij ik een interface maak met de functie injectNodesFinder, vervolgens moet de klasse deze methode implmenteren door de correct Finder-klasse op te geven (i.e. this.finder = new NodesFinder()).

Het enigste hierbij is dat alle deze klasses worden geimplementeerd in een [singleton] klasse.

Nu moet ik zeggen dat dit nou niet echt de meeste flexibele oplossing is als je van finder wilt switchen.... Omdat er nu eigenlijk nog steeds een "vaste" afhankelijkheid van mijn klasse met de NodesFinder-klasse. De perfect is het niet. Nu zou je dus een service locator kunnen gebruiken okm de juist nodesFinder instantie/klasse op te vragen...

Als ik het nu begrijp moet je kiezen tussen de afhankelijkheid van een service locator, of de correcte finder mee sturen via Constructor Injection, of interface injection. Nu heb je ook nog iets zoals Inversion of Control maar eerlijk gezegd snap ik daar allemaal niks van.

Nu is mijn vraag waarom zou ik Depency Injection ipv een Service locator genbruiken? Ik heb namelijk gevoel dat de depency injection het allemaal niet echt overzichtelijker maakt. Het vast iets wat verdomd handig is in de J2EE/EAA is.

[ Voor 4% gewijzigd door alienfruit op 11-04-2006 15:49 ]


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Dependency injection is zoals het woord zegt: dependencies injecteren op plekken waar het nodig is.

voorbeeld:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
interface EmployeeDoa{
   void saveOrUpdate(Employee e);
}

class HibernateEmployeeDao implements EmployeeDao{
   void saveOrUpdate(Employee e){... hibernate meuk ...}
}

interface EmployeeManager{
     void fire(long employeeId);
}

class EmployeeManagerImpl implements EmployeeManager{
     private EmployeeDao employeeDao;

    public EmployeeManagerImpl(){}

    public EmplyeeManagerImpl(EmployeeDao employeeDao){
        this.employeeDao = employeeDao;
    }

    public void setEmployeeDao(EmployeeDao employeeDao){
         this.employeeDao = employeeDao;
    }

    public void fire(long employeeId){
       Employee e = employeeDao.load(employeeId);
       e.fire();
       employeeDao.saveOrUpdate(e);
   }
}


Je ziet nu een EmployeeManagerImpl. Deze heeft een EmployeeDao nodig als dependency. Je zou er een HibernateEmployeeDao in kunnen drukken, maar voor het testen kun je ook eenvoudig een Mock versie van die interface erin kunnen prikken. Verder kun je 2 soorten injectie zien:
constructor injection (ik geef de dao mee via de constructor)
setter injection (ik geef de dao mee via de setter)
Uiteraard kies je voor je project meestal 1 stijl (mijn persoonlijke voorkeur heeft de constructor injection omdat je dan geen onnodige setters nodig bent en dat kan imho veel problemen voorkomen + je code minder complex maken (tenslotte hoef je geen rekening te houden met setters als ze er niet zijn)). het probleem aan constructor based injection is dat het qua schrijven meestal iets minder mooi is (vooral als je 5 of meer argumenten hebt). Daarom zie je ook heel vaak setter based dependency injection.

Maar wat is nu het voordeel?
Object zijn niet meer verantwoordelijk voor het verkrijgen van dependencies: dat laten ze over aan een ander. Ik doe dit via Spring: Spring is verantwoordelijk voor het oplijmen van al mijn beans en ook het setten van alle dependencies. Dus objecten die hoeven geen concrete implementaties meer aan te vragen -> objecten zijn beter te testen, zijn veel flexibeler. Verder reduceer je de 'lijm'code: code dat niets anders doet dan objecten in elkaar lijmen want dit kan ook allemaal gedaan worden door de IOC container (Spring in mijn geval dus). Hierdoor krijg je hele elegante en schone code. Verder heeft een IOC container nog heel veel extra features, zoals het transparant toevoegen van transacties en securty mbv AOP. Je kunt als je wilt zelf ook Aspecten maken: deze week hebben we bv een OptimisticLockingFailureRetryAspect gemaakt ivm optimistic locking failures in de database.

Dus ik neem aan dat het dependency injection wel duidelijk is.

Hoe zit het dan met het IOC gedeelte? IOC is een ruimer begrip: je maakt van je objecten een soortement van framework achtige componten: je objecten (de employeemanagerimpl bv) heeft al een bepaalde basis structuur, maar je kunt de details hierin varieeren (je zou bv een TopLinkEmployeeManager kunnen maken, alhoewel DAO`s imho niet zo eenvoudig uit te wisselen zijn).

Voor meer informatie zie:
Inversion of Control Containers and the Dependency Injection pattern

ps:
door te werken met een IOC-container, hoeft een object zich niet meer druk te maken hoe het aan dependencies komt. Het singleton design pattern is in IOC containers dan ook niet meer nodig (de container zorgt voor het aanmaken van de instantie en slaat die instantie ook op in een map) hierdoor heb je ook veel nieuwe mogelijkheden, bv scoping. Een instance zou bv een singleton kunnen zijn op request scope (bij iedere request moet eenmalig dit object aangemaakt worden), of op sessie scope, of applicatie scope of misschien zelfs wel serverscope of clusterscope :) Je legt dit soort verantwoordelijkheden niet meer bij het object neer, en daardoor krijg je veel inzichtelijkere en veel beter herbruikbare componenten.

[ Voor 15% gewijzigd door Alarmnummer op 11-04-2006 16:56 ]


  • -FoX-
  • Registratie: Januari 2002
  • Niet online

-FoX-

Carpe Diem!

Dependency injection, vaak ook gerefereerd als Inversion of Control, is eigenlijk een heel simpel principe. In plaats van gebruik te maken van een ServiceLocator, waarmee je je services / dependencies gaat opzoeken in het object waarin je het gaat gebruiken, ga je het via IoC gewoon aangeleverd krijgen.
Meer info: Fowler - Dependency Injection artikel

Het is in een bepaald opzicht wel vergelijkbaar met een Service Locator omdat je aan je referenties kan komen. Maar daar houdt de vergelijking wel op. IoC doet het tegenovergestelde (inversion) en de objecten krijgen hun dependencies toegespeeld.

Een goed voorbeeld voor het gebruik van IoC/DI is Spring. Hiermee lijm je je objecten aan elkaar en de Spring container voorziet je objecten dan van de nodige dependencies. Het leuke eraan is dat je zelf totaal geen dependencies op Spring nodig hebt. Geen geneuzel meer met "hoe kom ik aan mijn dependencies?"

Het ServiceLocator pattern op zich, is ook alleen maar ontstaan door de restricties die J2EE met zich meebracht (zoals JNDI lookups, EJB, ...). Dus waarom een workaround gebruiken voor zaken die je niet meer nodig hebt?

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 10:58

alienfruit

the alien you never expected

Topicstarter
Hartstikke bedankt voor de informaties. Ik ken de link van Fowler wel hoor alleen ik moet eerlijk toegeven dat ik het niet helemaal snapte. Maar jullie korte uitleg maak het allemaal een stuk begrijpelijker :) Ik zal er binnenkort eens mee pielen in Chrome. :)

[ Voor 20% gewijzigd door alienfruit op 11-04-2006 18:48 ]


  • tijn
  • Registratie: Februari 2000
  • Laatst online: 19-02 13:45
Hoe ervaren jullie de leercurve eigenlijk die met IoC gepaard gaat? Ik ben er nu een tijdje mee bezig (Castle op .NET) en het duurde toch wel behoorlijk lang voordat het kwartje eindelijk viel. Nu het eenmaal gevallen is zie ik pas de enorme mogelijkheden, maar als ik daar dan enthousiast verslag van probeer te doen ontmoet ik voor het merendeel glazige blikken. Af en toe vraag ik me af of het niet iets te hoog gegrepen is in een situatie waar je met een team werkt. Per slot van rekening zal toch iedereen het concept moeten snappen anders kun je er beter niet aan beginnen lijkt me.

Cuyahoga .NET website framework


  • JKVA
  • Registratie: Januari 2004
  • Niet online

JKVA

Design-by-buzzword fanatic

tijn schreef op dinsdag 11 april 2006 @ 19:13:
Af en toe vraag ik me af of het niet iets te hoog gegrepen is in een situatie waar je met een team werkt. Per slot van rekening zal toch iedereen het concept moeten snappen anders kun je er beter niet aan beginnen lijkt me.
Ach, niet iedereen hoeft te weten hoe de applicatie in elkaar gelijmd wordt. Als je een datalaag ontwikkelaar hebt, die zal het misschien zelfs aan zijn reet roesten welke taal/framework gebruikt wordt. Een ontwikkelaar van de weblaag zal het ook niet zo veel interesseren.

Uiteindelijk komt het er vooral op neer dat de architect het voor 100% begrijpt en het in een niet al te lange tijd duidelijk kan maken aan de anderen. Of ze precies alle pros en cons weten is een tweede, als ze er maar mee kunnen werken. Voor het maken van de meeste schermen en functionaliteit erachter hoef je niet veel van de architectuur te weten. Als je maar weet welke klassen je moet maken en welke methoden je moet aanroepen is het al redelijk werkbaar.

Nu begrijp ik ook wel dat een beetje overtuiging van de projectleden wel handig is, misschien zelfs wel essentieel, maar wat ik vooral wil zeggen is dat je een iets complexere constructie niet altijd links moet laten liggen omdat er een paar projectleden het misschien niet snappen.

Er zijn zoveel projecten waar lang niet alle mensen de volgende zaken grondig kennen: Tiles, Hibernate, Tapestry, JSF, iBatis, Spring (inkoppertje in dit draadje :) ), maar ook zaken als JavaScript of JasperReports. Ik noem maar een paar termen die je in een willekeurig project zo tegen kunt komen. Als er maar een paar 1337 mensen zijn op dat gebied en de rest daarmee kunnen assisteren, zie ik geen grote problemen.

[ Voor 11% gewijzigd door JKVA op 11-04-2006 22:25 ]

Fat Pizza's pizza, they are big and they are cheezy

Pagina: 1