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

  1. Poboljšanje testabilnosti: Lakše je zameniti sa mock-ovima/stub-ovima tokom modularnog testiranja.
  2. Oslabljenje povezanosti (Loose Coupling): Komponente su manje zavisne od konkretnih implementacija zavisnosti.
  3. Povećanje fleksibilnosti i proširivosti: Lako je menjati implementacije zavisnosti bez promene osnovnog koda.
  4. 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.