Sobes.tech
Junior

Mis on sõltuvuslik integreerimine ja millist kasu see toob?

sobes.tech AI

Vastus AI-lt

Sõltuvuste süstimine (Dependency Injection, DI) on disainimuster, kus komponendid saavad sõltuvused väljastpoolt, mitte ise neid luua. See on Inversiooni kontrolli (Inversion of Control, IoC) põhimõte.

DI kasu:

  1. Testimise lihtsustamine: Moodulitestide puhul on lihtsam asendada sõltuvused vahetustega (mocks/stubs).
  2. Lahus sidumine (Loose Coupling): Komponendid sõltuvad vähem konkreetsetest teostustest.
  3. Paindlikkuse ja laiendatavuse suurendamine: Võimalik hõlpsasti muuta sõltuvuste teostusi ilma põhikoodi muutmata.
  4. Lugemise ja hoolduse parandamine: Selgelt näha, millised sõltuvused on komponendile vajalikud.

Näide ilma DI ja koos DI-ga:

Ilma DI:

// Klass, mis loob sõltuvuse sees
public class ServiceA {
    private DatabaseConnection dbConnection;

    public ServiceA() {
        // Tugev seos: otsene konkreetse teostuse loomine
        this.dbConnection = new OracleConnection(); 
    }

    public void doSomething() {
        dbConnection.connect();
        // ...
    }
}

Koos DI-ga (konstruktoriga):

// Sõltuvuse liides
public interface DatabaseConnection {
    void connect();
    void disconnect();
}

// Erinevad teostused
public class OracleConnection implements DatabaseConnection {
    @Override
    public void connect() {
        System.out.println("Ühendub Oracle'iga...");
    }
    @Override
    public void disconnect() {
        System.out.println("Lõpetab ühenduse Oracle'iga...");
    }
}

public class MySQLConnection implements DatabaseConnection {
    @Override
    public void connect() {
        System.out.println("Ühendub MySQL'iga...");
    }
    @Override
    public void disconnect() {
        System.out.println("Lõpetab ühenduse MySQL'iga...");
    }
}

// Klass, mis saab sõltuvuse väljastpoolt
public class ServiceB {
    private DatabaseConnection dbConnection;

    // Sõltuvuse süstimine konstruktoriga
    public ServiceB(DatabaseConnection dbConnection) {
        this.dbConnection = dbConnection;
    }

    public void doSomething() {
        dbConnection.connect();
        // ...
    }

    public void setDbConnection(DatabaseConnection dbConnection) {
        this.dbConnection = dbConnection;
    }
}

// Kood, mis teostab süstimise (konfiguratsioon)
public class Application {
    public static void main(String[] args) {
        // Sõltuvuse loomine
        DatabaseConnection connection = new MySQLConnection(); 
        // Sõltuvuse süstimine ServiceB-sse
        ServiceB service = new ServiceB(connection); 
        service.doSomething();

        // Või sõltuvuse muutmine ilma ServiceB muutmata
        DatabaseConnection anotherConnection = new OracleConnection();
         ServiceB anotherService  = new ServiceB(anotherConnection);
         anotherService.doSomething();
    }
}

Süstimise viisid:

  • Konstruktoriga (Constructor Injection): Sõltuvused antakse läbi klassi konstruktor. Sobib kohustuslikele sõltuvustele.
  • Sätete kaudu (Setter Injection): Sõltuvused antakse sätete meetodite kaudu. Sobib valikulistele sõltuvustele.
  • Välja kaudu (Field Injection): Sõltuvused süstitakse otse klassi väljadele (tavaliselt kasutusel raamistikudega, nõuab refleksiooni). Ei soovitata ilma DI raamistiketa, kuna keerulisem testimine ja varjatud sõltuvused.

DI sageli realiseeritakse DI konteinerite/raamistikudega, nagu Spring, Guice, Dagger, mis haldavad objektide elutsüklit ja automatiseerivad süstimise protsessi.