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.