Sobes.tech
Junior
166

У чему се састоји особина убризгавања зависности (Dependency Injection)?

Одговор од АИ

sobes.tech АИ

Особеност внедрења зависности (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 Injection): Зависности се преносе кроз јавне методе-сетере. Омогућава креирање објеката са зависностима по потреби, али захтева додатне провере на null и не гарантује присуство свих зависности одмах.

    // Класа са зависношћу
    public class AnotherService {
        private AnotherDependency dependency;
    
        // Празан конструктор
        public AnotherService() {
        }
    
        // Увођење кроз сетер
        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!");
        }
    }
    

Упоређење начина увођења:

Начин увођења Предности Недостаци
Кроз конструктор Гарантује присуство зависности, лако тестирање, неизменљивост Може довести до "параметрозависности" конструктора при великом броју зависности
Кроз сетер Опционалност зависности, могућност промене зависности након креирања Захтева провере за null, не гарантује потпуно стање објекта након креирања
Кроз поље Кратак синтаксиса Јако зависно од DI-фрејмворка, отежава тестирање без фрејмворка

DI је кључни принцип у многим савременим фрејмворцима (нпр. Spring, CDI) и доприноси стварању слабо повезаних и лако тестираних апликација.