Junior
Šta je zavisna integracija i kakve koristi donosi?
sobes.tech АИ
Одговор од АИ
Umetanje zavisnosti (Dependency Injection, DI) je obrazac dizajna u kojem komponente dobijaju zavisnosti spolja, a ne ih same kreiraju. To je jedan od principa Inversion of Control (IoC).
Prednosti DI:
- Poboljšanje testabilnosti: Lakše je zameniti sa mock-ovima/stub-ovima tokom modularnog testiranja.
- Oslabljenje povezanosti (Loose Coupling): Komponente su manje zavisne od konkretnih implementacija zavisnosti.
- Povećanje fleksibilnosti i proširivosti: Lako je menjati implementacije zavisnosti bez promene osnovnog koda.
- Poboljšanje čitljivosti i održivosti: Jasno je vidljivo koje su zavisnosti potrebne komponenti.
Primeri bez DI i sa DI:
Bez DI:
// Klasa koja kreira zavisnost unutar sebe
public class ServiceA {
private DatabaseConnection dbConnection;
public ServiceA() {
// Jaka povezanost: eksplicitno kreiramo konkretnu implementaciju
this.dbConnection = new OracleConnection();
}
public void doSomething() {
dbConnection.connect();
// ...
}
}
Sa DI (kroz konstruktor):
// Interfejs zavisnosti
public interface DatabaseConnection {
void connect();
void disconnect();
}
// Različite implementacije
public class OracleConnection implements DatabaseConnection {
@Override
public void connect() {
System.out.println("Povezivanje sa Oracle...");
}
@Override
public void disconnect() {
System.out.println("Odjavljivanje sa Oracle...");
}
}
public class MySQLConnection implements DatabaseConnection {
@Override
public void connect() {
System.out.println("Povezivanje sa MySQL...");
}
@Override
public void disconnect() {
System.out.println("Odjavljivanje sa MySQL...");
}
}
// Klasa koja prima zavisnost spolja
public class ServiceB {
private DatabaseConnection dbConnection;
// Umetanje zavisnosti putem konstruktora
public ServiceB(DatabaseConnection dbConnection) {
this.dbConnection = dbConnection;
}
public void doSomething() {
dbConnection.connect();
// ...
}
public void setDbConnection(DatabaseConnection dbConnection) {
this.dbConnection = dbConnection;
}
}
// Kod za konfiguraciju
public class Application {
public static void main(String[] args) {
// Kreiranje zavisnosti
DatabaseConnection connection = new MySQLConnection();
// Umetanje zavisnosti u ServiceB
ServiceB service = new ServiceB(connection);
service.doSomething();
// Ili zamena zavisnosti bez promene ServiceB
DatabaseConnection anotherConnection = new OracleConnection();
ServiceB anotherService = new ServiceB(anotherConnection);
anotherService.doSomething();
}
}
Metode umetanja:
- Kroz konstruktor (Constructor Injection): Zavisnosti se obezbeđuju kroz konstruktor klase. Prednost za obavezne zavisnosti.
- Kroz seter (Setter Injection): Zavisnosti se obezbeđuju putem metoda-settera. Pogodno za opcionalne zavisnosti.
- Kroz polje (Field Injection): Zavisnosti se direktno ubrizgavaju u polja klase (obično sa okvirima, zahteva refleksiju). Ne preporučuje se bez DI okvira zbog otežanog testiranja i skrivanja zavisnosti.
DI se često implementira pomoću DI kontejnera/okvira kao što su Spring, Guice, Dagger, koji upravljaju životnim ciklusom objekata i automatizuju proces umetanja.