Sobes.tech
Junior

V čom spočíva vlastnosť zavádzania závislostí (Dependency Injection)?

sobes.tech AI

Odpoveď od AI

Osobitosť zavádzania závislostí (DI) spočíva v tom, že vytváranie a riadenie závislostí objektu sa presúva z samotného objektu von, zvyčajne do IoC kontajnera (Inversion of Control). Namiesto toho, aby si objekt sám vytváral alebo našiel svoje závislosti, sú "vstrekované" zvonku.

Hlavné výhody a vlastnosti DI:

  • Oddelenie zodpovednosti: Trieda nenesie zodpovednosť za vytváranie svojich závislostí.
  • Testovateľnosť: Závislosti je ľahké nahradiť mockmi alebo záškrtmi pri modulárnom testovaní.
  • Flexibilita: Jednoducho meniť implementácie závislostí bez zmeny kódu, ktorý ich používa.
  • Menšia prepojenosť: Komponenty sú menej pevne prepojené, čo zlepšuje udržiavateľnosť.

Spôsoby zavádzania:

  • Cez konštruktor (Constructor Injection): Závislosti sa prenášajú cez konštruktor triedy. Najpreferovanejší spôsob, pretože garantuje prítomnosť závislostí od momentu vytvorenia objektu.

    // Trieda so závislosťou
    public class MyService {
        private MyDependency dependency;
    
        // Zavedenie cez konštruktor
        public MyService(MyDependency dependency) {
            this.dependency = dependency;
        }
    
        // Použitie závislosti
        public void doSomething() {
            dependency.performAction();
        }
    }
    
    // Závislosť
    public interface MyDependency {
        void performAction();
    }
    
    // Príklad implementácie závislosti
    public class MyDependencyImpl implements MyDependency {
        @Override
        public void performAction() {
            System.out.println("Action performed!");
        }
    }
    
  • Cez setter (Setter Injection): Závislosti sa prenášajú cez verejné metódy-setre. Umožňuje vytvárať objekty so závislosťami na požiadanie, ale vyžaduje ďalšie kontroly na null a nezaručuje prítomnosť všetkých závislostí naraz.

    // Trieda so závislosťou
    public class AnotherService {
        private AnotherDependency dependency;
    
        // Prázdny konštruktor
        public AnotherService() {
        }
    
        // Zavedenie cez setter
        public void setDependency(AnotherDependency dependency) {
            this.dependency = dependency;
        }
    
        // Použitie závislosti
        public void doSomethingElse() {
            if (dependency != null) {
                dependency.anotherAction();
            } else {
                System.out.println("Dependency is not set!");
            }
        }
    }
    
    // Závislosť
    public interface AnotherDependency {
        void anotherAction();
    }
    
    // Príklad implementácie závislosti
    public class AnotherDependencyImpl implements AnotherDependency {
        @Override
        public void anotherAction() {
            System.out.println("Another action performed!");
        }
    }
    
  • Cez pole (Field Injection): Závislosti sa vkladajú priamo do polí triedy pomocou anotácií. Najjednoduchší syntakticky, ale robí triedu závislou od DI-frameworku a sťažuje testovanie bez frameworku.

    import org.springframework.beans.factory.annotation.Autowired;
    
    // Trieda so závislosťou
    public class SomeOtherService {
    
        // Zavedenie cez pole (s použitím Spring anotácie)
        @Autowired
        private YetAnotherDependency dependency;
    
        // Použitie závislosti
        public void doYetAnotherThing() {
            dependency.performYetAnotherAction();
        }
    }
    
    // Závislosť
    public interface YetAnotherDependency {
        void performYetAnotherAction();
    }
    
    // Príklad implementácie závislosti
    public class YetAnotherDependencyImpl implements YetAnotherDependency {
        @Override
        public void performYetAnotherAction() {
            System.out.println("Yet another action performed!");
        }
    }
    

Porovnanie spôsobov zavádzania:

Spôsob zavádzania Výhody Nevýhody
Cez konštruktor Zaručuje prítomnosť závislostí, ľahké testovanie, nemennosť Môže viesť k "parametrozávislosti" konštruktora pri veľkom počte závislostí
Cez setter Voliteľnosť závislostí, možnosť zmeny závislostí po vytvorení Vyžaduje kontroly na null, nezaručuje úplný stav objektu po vytvorení
Cez pole Krátky syntax Silná závislosť od DI-frameworku, sťažuje testovanie bez frameworku

DI je kľúčovým princípom v mnohých moderných frameworkoch (napríklad Spring, CDI) a prispieva k vytváraniu slabšie prepojených a ľahko testovateľných aplikácií.