Sobes.tech
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:

  1. Zlepšenie testovateľnosti: Jednoduchšie je nahradiť závislosti pomocou mockov/stubov pri modulárnom testovaní.
  2. Uvoľnenie väzby (Loose Coupling): Komponenty sú menej závislé od konkrétnych implementácií závislostí.
  3. Zvýšenie flexibility a rozšíriteľnosti: Jednoducho možno meniť implementácie závislostí bez zmeny hlavného kódu.
  4. 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.