Sobes.tech
Junior

Kuo išsiskiria priklausomybių injekcijos (Dependency Injection) ypatybė?

sobes.tech AI

Atsakymas iš AI

Priklausomybių įdiegimo (DI) ypatybė yra ta, kad objekto priklausomybių kūrimas ir valdymas yra perkeliami iš paties objekto į išorę, dažniausiai į IoC konteinerį (Inversion of Control). Vietoj to, kad objektas pats sukurtų ar rastų savo priklausomybes, jos "įdiegia" į jį iš išorės.

Pagrindiniai DI privalumai ir ypatybės:

  • Atsakomybės pasidalijimas: Klasė neatsako už savo priklausomybių kūrimą.
  • Testavimas: Priklausomybes lengva pakeisti su mokslais ar užuominomis modulinio testavimo metu.
  • Lankstumas: Lengva keisti priklausomybių įgyvendinimus be kodo keitimo, kuris jas naudoja.
  • Mažesnė susijungimas: Komponentai tampa mažiau stipriai susiję, tai gerina palaikymą.

Įdiegimo būdai:

  • Per konstruktorių (Constructor Injection): Priklausomybes perduodamos per klasės konstruktorių. Labiausiai pageidaujamas būdas, nes garantuoja priklausomybių buvimą nuo objekto sukūrimo momento.

    // Su priklausomybe klasė
    public class MyService {
        private MyDependency dependency;
    
        // Per konstruktorių
        public MyService(MyDependency dependency) {
            this.dependency = dependency;
        }
    
        // Naudojant priklausomybes
        public void doSomething() {
            dependency.performAction();
        }
    }
    
    // Priklausomybė
    public interface MyDependency {
        void performAction();
    }
    
    // Pavyzdinė priklausomybės įgyvendinimo klasė
    public class MyDependencyImpl implements MyDependency {
        @Override
        public void performAction() {
            System.out.println("Veiksmas atliktas!");
        }
    }
    
  • Per nustatymo metodą (Setter Injection): Priklausomybes perduodamos per viešus seterių metodus. Leidžia kurti objektus su priklausomybėmis pagal poreikį, bet reikalauja papildomų patikrinimų dėl null ir nesuteikia garantijos, kad visos priklausomybės bus iš karto.

    // Su priklausomybe klasė
    public class AnotherService {
        private AnotherDependency dependency;
    
        // Tuščias konstruktorius
        public AnotherService() {
        }
    
        // Per nustatymo metodą
        public void setDependency(AnotherDependency dependency) {
            this.dependency = dependency;
        }
    
        // Naudojant priklausomybes
        public void doSomethingElse() {
            if (dependency != null) {
                dependency.anotherAction();
            } else {
                System.out.println("Priklausomybė nėra nustatyta!");
            }
        }
    }
    
    // Priklausomybė
    public interface AnotherDependency {
        void anotherAction();
    }
    
    // Pavyzdinė priklausomybės įgyvendinimo klasė
    public class AnotherDependencyImpl implements AnotherDependency {
        @Override
        public void anotherAction() {
            System.out.println("Kita veiksmo atlikimas!");
        }
    }
    
  • Per lauką (Field Injection): Priklausomybes įdedamos tiesiogiai į klasės laukus naudojant anotacijas. Labiausiai sintaksiškai paprastas, bet daro klasę priklausomą nuo DI karkaso ir apsunkina testavimą be karkaso.

    import org.springframework.beans.factory.annotation.Autowired;
    
    // Su priklausomybe klasė
    public class SomeOtherService {
    
        // Per lauką (naudojant Spring anotaciją)
        @Autowired
        private YetAnotherDependency dependency;
    
        // Naudojant priklausomybes
        public void doYetAnotherThing() {
            dependency.performYetAnotherAction();
        }
    }
    
    // Priklausomybė
    public interface YetAnotherDependency {
        void performYetAnotherAction();
    }
    
    // Pavyzdinė priklausomybės įgyvendinimo klasė
    public class YetAnotherDependencyImpl implements YetAnotherDependency {
        @Override
        public void performYetAnotherAction() {
            System.out.println("Dar viena veiksmo atlikimas!");
        }
    }
    

Palyginimas tarp įdiegimo būdų:

Įdiegimo būdas Privalumai Trūkumai
Per konstruktorių Garantuoja priklausomybių buvimą, lengva testuoti, nekeičiama Gali sukelti "parametrų priklausomybės" konstruktoriuje, jei daug priklausomybių
Per nustatymo metodą Pasirinktinumas priklausomybių, galimybė keisti priklausomybes po sukūrimo Reikalauja patikrinimų dėl null, nesuteikia garantijos, kad objektas yra pilnai paruoštas po sukūrimo
Per lauką Trumpas sintaksis Stipri priklausomybė nuo DI karkaso, apsunkina testavimą be jo

DI yra pagrindinis principas daugelyje šiuolaikinių karkasų (pvz., Spring, CDI) ir padeda kurti silpnai susietas ir lengvai testuojamas programas.