Junior
Čo je závislá integrácia a aký má prínos?
sobes.tech AI
Odpoveď od AI
Vkladanie závislostí (Dependency Injection, DI) je návrhový vzor, pri ktorom komponenty získavajú závislosti zvonku, namiesto toho, aby si ich samy vytvárali. Ide o jeden z princípov Inversion of Control (IoC).
Výhody DI:
- Zlepšenie testovateľnosti: Jednoduchšie je nahradiť závislosti pomocou mockov/stubov pri modulárnom testovaní.
- Uvoľnenie väzby (Loose Coupling): Komponenty sú menej závislé od konkrétnych implementácií závislostí.
- Zvýšenie flexibility a rozšíriteľnosti: Jednoducho možno meniť implementácie závislostí bez zmeny hlavného kódu.
- Zlepšenie čitateľnosti a údržby: Jasne je vidieť, aké závislosti sú potrebné komponentu.
Príklady bez DI a s DI:
Bez DI:
// Trieda, ktorá vytvára závislosť vo vnútri seba
public class ServiceA {
private DatabaseConnection dbConnection;
public ServiceA() {
// Silná väzba: explicitne vytvárame konkrétnu implementáciu
this.dbConnection = new OracleConnection();
}
public void doSomething() {
dbConnection.connect();
// ...
}
}
S DI (cez konštruktor):
// Rozhranie závislosti
public interface DatabaseConnection {
void connect();
void disconnect();
}
// Rôzne implementácie
public class OracleConnection implements DatabaseConnection {
@Override
public void connect() {
System.out.println("Pripájanie k Oracle...");
}
@Override
public void disconnect() {
System.out.println("Odpojenie od Oracle...");
}
}
public class MySQLConnection implements DatabaseConnection {
@Override
public void connect() {
System.out.println("Pripájanie k MySQL...");
}
@Override
public void disconnect() {
System.out.println("Odpojenie od MySQL...");
}
}
// Trieda, ktorá prijíma závislosť zvonku
public class ServiceB {
private DatabaseConnection dbConnection;
// Vkladanie závislosti cez konštruktor
public ServiceB(DatabaseConnection dbConnection) {
this.dbConnection = dbConnection;
}
public void doSomething() {
dbConnection.connect();
// ...
}
public void setDbConnection(DatabaseConnection dbConnection) {
this.dbConnection = dbConnection;
}
}
// Kód na konfiguráciu
public class Application {
public static void main(String[] args) {
// Vytvorenie závislosti
DatabaseConnection connection = new MySQLConnection();
// Vloženie závislosti do ServiceB
ServiceB service = new ServiceB(connection);
service.doSomething();
// Alebo zmena závislosti bez zmeny ServiceB
DatabaseConnection anotherConnection = new OracleConnection();
ServiceB anotherService = new ServiceB(anotherConnection);
anotherService.doSomething();
}
}
Spôsoby zavádzania:
- Cez konštruktor (Constructor Injection): Závislosti sú poskytované cez konštruktor triedy. Uprednostňuje sa pre povinné závislosti.
- Cez setter (Setter Injection): Závislosti sú poskytované cez metódy-settery. Vhodné pre voliteľné závislosti.
- Cez pole (Field Injection): Závislosti sú vkladané priamo do polí triedy (zvyčajne s frameworkmi, vyžaduje reflexiu). Neodporúča sa bez DI frameworkov kvôli zložitosti testovania a skrytiu závislostí.
DI sa často realizuje pomocou DI kontajnerov/frameworkov ako Spring, Guice, Dagger, ktoré spravujú životný cyklus objektov a automatizujú proces vkladania.