Java-Dependency Injection design mønster tillater oss å fjerne hard-kodet avhengigheter og gjøre vårt program løst koplet, utvides og stabile. Vi kan implementere dependency injection i java for å flytte avhengighet oppløsning fra kompilere-tid til kjøring.,
Java-Dependency Injection
Java-Dependency injection synes vanskelig å ta tak i med teori, så jeg ville ta et enkelt eksempel, og da vil vi se hvordan å bruke dependency injection mønster for å oppnå løs kopling og extendability i programmet.
La oss si at vi har et program der vi forbruker EmailService
for å sende e-post. Normalt ville vi implementere dette som nedenfor.
EmailService
klasse har logikk for å sende en e-post melding til mottaker e-post adresse., Vår søknad kode vil bli som nedenfor.
Vår klient koden som du vil bruke MyApplication
klassen til å sende e-postmeldinger vil bli som nedenfor.
Ved første blikk, det ser ingenting galt med over gjennomføringen. Men koden ovenfor logikk har visse begrensninger.
-
MyApplication
klassen er ansvarlig for å initialisere e-tjenesten og deretter bruke det. Dette fører til hard-kodet avhengighet. Hvis vi ønsker å bytte til noen andre avanserte e-tjenesten i fremtiden, vil det kreve endringer i koden i MyApplication klasse., Dette gjør programmet vårt hardt for å utvide og hvis e-service er brukt i flere klasser da det ville bli enda vanskeligere. - Hvis vi ønsker å utvide vårt program for å gi en ekstra messaging-funksjonen, for eksempel SMS eller Facebook-melding så vi måtte ha for å skrive et nytt program for det. Dette vil innebære endringer i koden i programmet klasser og i klient klasser også.
- Testing programmet vil være svært vanskelig siden vår søknad er direkte opprette e-tjenesten som eksempel. Det er ingen måte vi kan håne disse objektene i vår test klasser.,
Man kan argumentere for at vi kan fjerne den e-posttjeneste eksempel etablering fra MyApplication
klasse ved å ha en konstruktør som krever e-tjenesten, som et argument.
Men i dette tilfellet, vi ber klienten programmer eller test klasser for å initialisere e-tjenesten er ikke en god utforming avgjørelse.
la oss Nå se hvordan vi kan bruke java-dependency injection mønster til å løse alle problemer med ovennevnte gjennomføring., Dependency Injection i java krever minst følgende:
- Service-komponenter bør være utformet med base klasse eller grensesnitt. Det er bedre å foretrekke grensesnitt eller abstrakte klasser som skulle definere kontrakt for tjenester.
- Forbruker klasser bør være skriftlig i form av service-grensesnitt.
- Injektor klasser som vil kreve at tjenestene og da forbrukeren klasser.
Java-Dependency Injection – Service-Komponenter
For vårt tilfelle, kan vi ha MessageService
som vil erklære kontrakten for service-implementeringer.,
package com.journaldev.java.dependencyinjection.service;public interface MessageService {void sendMessage(String msg, String rec);}
la oss Nå si at vi har E-post-og SMS-tjenester som implementerer over grensesnitt.
Vår avhengighet injeksjon java-tjenester er klare og nå kan vi skrive våre consumer klasse.
Java-Dependency Injection – Service Forbruker
Vi er ikke nødvendig å ha base-grensesnitt for forbruker-klasser, men jeg vil ha en Consumer
grensesnitt erklære kontrakt for forbruker-klasser.
package com.journaldev.java.dependencyinjection.consumer;public interface Consumer {void processMessages(String msg, String rec);}
Min forbruker klasse implementering er som nedenfor.
legg Merke til at søknaden vår klasse er det bare å bruke tjenesten., Det gjør ikke initialisere tjenesten som fører til bedre «separasjon av bekymringer». Også bruk av tjenesten grensesnittet gjør det mulig for oss å enkelt test programmet ved tentamen MessageService og binder tjenestene ved kjøring snarere enn å kompilere tid.
Nå er vi klar til å skrive java-avhengighet injektor klasser som vil kreve tjenesten og også forbruker klasser.
Java-Dependency Injection – Sprøytebrukere Klasser
La oss ta et grensesnitt MessageServiceInjector
med metoden erklæring som returnerer Consumer
klasse.,
package com.journaldev.java.dependencyinjection.injector;import com.journaldev.java.dependencyinjection.consumer.Consumer;public interface MessageServiceInjector {public Consumer getConsumer();}
Nå for hver service, vi er nødt til å lage injektor klasser som nedenfor.
package com.journaldev.java.dependencyinjection.injector;import com.journaldev.java.dependencyinjection.consumer.Consumer;import com.journaldev.java.dependencyinjection.consumer.MyDIApplication;import com.journaldev.java.dependencyinjection.service.EmailServiceImpl;public class EmailServiceInjector implements MessageServiceInjector {@Overridepublic Consumer getConsumer() {return new MyDIApplication(new EmailServiceImpl());}}
package com.journaldev.java.dependencyinjection.injector;import com.journaldev.java.dependencyinjection.consumer.Consumer;import com.journaldev.java.dependencyinjection.consumer.MyDIApplication;import com.journaldev.java.dependencyinjection.service.SMSServiceImpl;public class SMSServiceInjector implements MessageServiceInjector {@Overridepublic Consumer getConsumer() {return new MyDIApplication(new SMSServiceImpl());}}
la oss Nå se hvordan vår klient programmer vil bruke programmet med et enkelt program.
Som du kan se at vår søknad klasser er kun ansvarlig for bruk av tjenesten. Service klasser er opprettet i sprøytebrukere. Også hvis vi har å ytterligere utvide vår applikasjon for å tillate facebook meldinger, og vi er nødt til å skrive Tjeneste klasser og injektor klasser bare.,
Slik avhengighet injeksjon gjennomføring løst problemet med hard-kodet avhengighet og hjulpet oss i å gjøre våre programmet er fleksibelt og lett å utvide. La oss nå se hvor lett vi kan teste vår søknad klasse av tentamen injektor og service klasser.
Java-Dependency Injection – JUnit Test med Mock Injektor og Service
Som du kan se at jeg bruker anonyme klasser for å håne den injektor og service klasser, og jeg kan enkelt teste programmet mitt metoder., Jeg bruker JUnit 4 for ovennevnte test klasse, så sørg for at det er i prosjektet bygge banen hvis du kjører over teste klasse.
Vi har brukt konstruktører for å injisere den avhengigheter i programmet klasser, en annen måte er å bruke en setter metode for å injisere avhengigheter i programmet klasser. For fuglehunden metode dependency injection, vår søknad klasse vil bli implementert som nedenfor.
package com.journaldev.java.dependencyinjection.injector;import com.journaldev.java.dependencyinjection.consumer.Consumer;import com.journaldev.java.dependencyinjection.consumer.MyDIApplication;import com.journaldev.java.dependencyinjection.service.EmailServiceImpl;public class EmailServiceInjector implements MessageServiceInjector {@Overridepublic Consumer getConsumer() {MyDIApplication app = new MyDIApplication();app.setService(new EmailServiceImpl());return app;}}
En av de beste eksempel på fuglehunden dependency injection er Struts2 Servlet API Klar grensesnitt.,
Om du skal bruke Konstruktøren basert avhengighet injeksjon eller setter basert er en design-vedtak og avhenger av ditt behov. For eksempel, hvis søknaden ikke kan fungere i det hele tatt uten tjenesten klasse så ville jeg foretrekker constructor basert DI eller annet jeg ville gå for fuglehunden metode basert DI du bruker den bare når det er virkelig trengte.
Dependency Injection i Java er en måte å oppnå Inversion of control (IoC) i vårt program ved å flytte objekter bindende fra kompilere tid til kjøring., Vi kan oppnå IoC gjennom Fabrikken Mønster, Mal Metode Design Mønster, Strategi Mønster og Service Locator mønster også.
Våren Dependency Injection, Google Guice og Java EE CDI rammer forenkle prosessen for avhengighet injeksjon gjennom bruk av Java Reflection API og java-kommentarer. Alt vi trenger er å legge inn merknader i feltet, konstruktør eller setter metode og konfigurere dem i konfigurasjonen xml-filer eller klasser.,sjon
Noen av fordelene ved å bruke Dependency Injection i Java er:
- Separasjon av Bekymringer
- Boilerplate-Kode reduksjon i programmet klasser fordi alle arbeide for å initialisere avhengigheter er håndtert av injektoren komponent
- Konfigurerbar komponenter gjør programmet lett utvides
- Unit testing er lett med mock-objekter
Ulemper av Java-Dependency Injection
Java-Dependency injection har noen ulemper også:
- Hvis du for mye, kan det føre til vedlikehold problemer fordi effekten av endringene er kjent under kjøring.,
- Dependency injection i java skjuler tjenesten klasse avhengigheter som kan føre til runtime feil som ville ha blitt fanget på kompilere tid.
Det er alt for dependency injection mønster i java. Det er bra å vite og bruke det når vi er i kontroll over tjenestene.