რა არის დამოკიდებულებების შეყვანის (Dependency Injection) თავისებურება?
sobes.tech AI
პასუხი AI-სგან
Тәуелділіктерді енгізудің (DI) ерекшелігі — бұл объектінің тәуелділіктерін құру және басқару оның өзінен сыртқа, әдетте IoC контейнеріне (Inversion of Control) ауыстырылуы. Объект өз тәуелділіктерін өзі құрып немесе табудың орнына, олар сырттан "енгізіледі".
DI-нің негізгі артықшылықтары мен ерекшеліктері:
- Жауапкершілікті бөлу: Класс өз тәуелділіктерін құру жауапкершілігін алмайды.
- Тестілеу оңайлығы: Тәуелділіктерді моктар немесе жасанды объектілермен оңай ауыстыруға болады.
- Икемділік: Тәуелділіктердің жүзеге асырылуын өзгерту кодты өзгертусіз оңай жүзеге асырылады.
- Аз байланыс: Компоненттер аз байланысқан, бұл қолдауды жақсартады.
Енгізу тәсілдері:
-
Конструктор арқылы (Constructor Injection): Тәуелділіктер кластың конструкторы арқылы беріледі. Бұл ең жақсы тәсіл, себебі ол объект құру кезінде тәуелділіктердің бар болуын кепілдейді.
// Тәуелділігі бар класс public class MyService { private MyDependency dependency; // Конструктор арқылы енгізу public MyService(MyDependency dependency) { this.dependency = dependency; } // Тәуелділікті пайдалану public void doSomething() { dependency.performAction(); } } // Тәуелділік public interface MyDependency { void performAction(); } // Тәуелділіктің жүзеге асырылуы public class MyDependencyImpl implements MyDependency { @Override public void performAction() { System.out.println("Action performed!"); } } -
Setter арқылы (Setter Injection): Тәуелділіктер қоғамдық әдістер арқылы беріледі. Бұл объектілерді қажетті тәуелділіктермен құруға мүмкіндік береді, бірақ қосымша null тексерулерін талап етеді және барлық тәуелділіктердің бір уақытта болуын кепілдемейді.
// Тәуелділігі бар класс public class AnotherService { private AnotherDependency dependency; // Бос конструктор public AnotherService() { } // Setter арқылы енгізу public void setDependency(AnotherDependency dependency) { this.dependency = dependency; } // Тәуелділікті пайдалану public void doSomethingElse() { if (dependency != null) { dependency.anotherAction(); } else { System.out.println("Dependency is not set!"); } } } // Тәуелділік public interface AnotherDependency { void anotherAction(); } // Тәуелділіктің жүзеге асырылуы public class AnotherDependencyImpl implements AnotherDependency { @Override public void anotherAction() { System.out.println("Another action performed!"); } } -
Майданда (Field Injection): Тәуелділіктер тікелей сыныптың өрістеріне аннотациялар көмегімен енгізіледі. Бұл ең қарапайым синтаксис, бірақ ол DI-фреймворкке тәуелді етеді және тестілеуді қиындатады.
import org.springframework.beans.factory.annotation.Autowired; // Тәуелділігі бар класс public class SomeOtherService { // Майдан арқылы енгізу (Spring аннотациясы арқылы) @Autowired private YetAnotherDependency dependency; // Тәуелділікті пайдалану public void doYetAnotherThing() { dependency.performYetAnotherAction(); } } // Тәуелділік public interface YetAnotherDependency { void performYetAnotherAction(); } // Тәуелділіктің жүзеге асырылуы public class YetAnotherDependencyImpl implements YetAnotherDependency { @Override public void performYetAnotherAction() { System.out.println("Yet another action performed!"); } }
Салыстыру:
| Енгізу тәсілі | Артықшылықтары | Кемшіліктері |
|---|---|---|
| Конструктор арқылы | Қажетті тәуелділіктердің бар болуын кепілдейді, тестілеу оңай, өзгермейді | "Параметрлік тәуелділік" пайда болуы мүмкін, тәуелділіктер көп болғанда |
| Setter арқылы | Таңдау тәуелділіктері, тәуелділіктерді кейін өзгерту мүмкіндігі | Null тексерулерін талап етеді, объектінің толық күйін кепілдемейді |
| Майдан арқылы | Қысқа синтаксис | DI-фреймворкке тәуелді, тестілеуді қиындатады |
DI — бұл көптеген заманауи фреймворктердің (мысалы, Spring, CDI) негізгі принципі және ол әлсіз байланысты және оңай тестіленетін қолданбаларды құруға көмектеседі.