Sobes.tech
Junior

Какви видове внедряване на зависимости знаете?

sobes.tech AI

Отговор от AI

Има три основни вида:

  1. Внедряване чрез поле (Field Injection): Зависимостта се внедрява директно в полето на класа с помощта на анотация (например @Autowired в Spring). Лесно за използване, но усложнява модулното тестване и нарушава принципа на единствената отговорност, скривайки зависимостите.

    // Пример за внедряване чрез поле
    public class MyService {
        // Зависимостта се внедрява директно в полето
        @Autowired
        private MyRepository repository;
    
        public void doSomething() {
            repository.getData();
        }
    }
    
  2. Внедряване чрез сетър (Setter Injection): Зависимостта се внедрява чрез публичен метод-сетър. Позволява опционално наличие на зависимост (не е задължително да се зададе), удобно за промяна на зависимостите по време на изпълнение (макар и рядко да се използва). Не създава задължителна зависимост при създаване на обекта.

    // Пример за внедряване чрез сетър
    public class MyService {
        private MyRepository repository;
    
        // Зависимостта се внедрява чрез сетър
        @Autowired
        public void setRepository(MyRepository repository) {
            this.repository = repository;
        }
    
        public void doSomething() {
            repository.getData();
        }
    }
    
  3. Внедряване чрез конструктор (Constructor Injection): Зависимостта се внедрява чрез аргумент на конструктора. Е предпочитаният начин, тъй като осигурява задължителност на зависимостта (без нея обектът не може да бъде създаден), улеснява модулното тестване (лесно е да се предадат мок-обекти) и ясно декларира нуждите на класа. Прави обектите неизменяеми след създаването, ако полетата са final.

    // Пример за внедряване чрез конструктор
    public class MyService {
        private final MyRepository repository; // Поле може да бъде final
    
        // Зависимостта се внедрява чрез конструктор
        @Autowired // В новите версии на Spring може да се пропусне анотацията @Autowired за единствения конструктор
        public MyService(MyRepository repository) {
            this.repository = repository;
        }
    
        public void doSomething() {
            repository.getData();
        }
    }
    

Сравнителна таблица:

Вид внедряване Задължителност на зависимостта Простота на използване Тестируемост Непроменяемост
Чрез поле Опционално (скрито) Висока Ниска Не
Чрез сетър Опционално Средна Средна Не
Чрез конструктор Задължително Средна Висока Възможна

В повечето случаи се препоръчва използването на внедряване чрез конструктор.