Sobes.tech
Junior

Kas yra priklausoma integracija ir kokią naudą ji teikia?

sobes.tech AI

Atsakymas iš AI

Priklausomybių injekcija (Dependency Injection, DI) yra projektavimo šablonas, kai komponentai gauna priklausomybes iš išorės, o ne patys jas kuria. Tai yra Inversijos kontrolės (Inversion of Control, IoC) principas.

DI nauda:

  1. Testavimo patogumas: Modulinio testavimo metu lengviau pakeisti priklausomybes su pakaitalais (mocks/stubs).
  2. Laisvas sujungimas (Loose Coupling): Komponentai mažiau priklauso nuo konkrečių įgyvendinimų.
  3. Lankstumo ir plėtros galimybių didinimas: Lengvai galima keisti priklausomybių įgyvendinimus be pagrindinio kodo keitimo.
  4. Skaitomumo ir palaikymo gerinimas: Aiškiai matyti, kokios priklausomybės reikalingos komponentui.

Pavyzdys be DI ir su DI:

Be DI:

// Klasė, kuri sukuria priklausomybę viduje
public class ServiceA {
    private DatabaseConnection dbConnection;

    public ServiceA() {
        // Stiprus sujungimas: tiesiogiai kuriame konkretų įgyvendinimą
        this.dbConnection = new OracleConnection(); 
    }

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

Su DI (per konstruktorių):

// Priklausomybės sąsaja
public interface DatabaseConnection {
    void connect();
    void disconnect();
}

// Skirtingi įgyvendinimai
public class OracleConnection implements DatabaseConnection {
    @Override
    public void connect() {
        System.out.println("Jungiamasi prie Oracle...");
    }
    @Override
    public void disconnect() {
        System.out.println("Atsijungiama nuo Oracle...");
    }
}

public class MySQLConnection implements DatabaseConnection {
    @Override
    public void connect() {
        System.out.println("Jungiamasi prie MySQL...");
    }
    @Override
    public void disconnect() {
        System.out.println("Atsijungiama nuo MySQL...");
    }
}

// Klasė, gaunanti priklausomybę iš išorės
public class ServiceB {
    private DatabaseConnection dbConnection;

    // Priklausomybės injekcija per konstruktorių
    public ServiceB(DatabaseConnection dbConnection) {
        this.dbConnection = dbConnection;
    }

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

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

// Kodas, kuris atlieka injekciją (konfigūracija)
public class Application {
    public static void main(String[] args) {
        // Sukuriama priklausomybė
        DatabaseConnection connection = new MySQLConnection(); 
        // Injektuojama priklausomybė į ServiceB
        ServiceB service = new ServiceB(connection); 
        service.doSomething();

        // Arba pakeičiama priklausomybė be ServiceB keitimo
        DatabaseConnection anotherConnection = new OracleConnection();
         ServiceB anotherService  = new ServiceB(anotherConnection);
         anotherService.doSomething();
    }
}

Injekcijos būdai:

  • Per konstruktorių (Constructor Injection): Priklausomybės tiekiamos per klasės konstruktorių. Tinka būtinoms priklausomybėms.
  • Per seterį (Setter Injection): Priklausomybės tiekiamos per seter metodus. Tinka pasirinktiniams priklausomybėms.
  • Per lauką (Field Injection): Priklausomybės injekuojamos tiesiogiai į klasės laukus (dažnai naudojama su framework'ais, reikalauja refleksijos). Nerekomenduojama be DI framework'ų, nes apsunkina testavimą ir slepia priklausomybes.

DI dažnai realizuojama naudojant DI konteinerius/framework'us, tokius kaip Spring, Guice, Dagger, kurie valdo objektų gyvavimo ciklą ir automatizuoja injekcijos procesą.