← Назад к вопросам

Что такое dependency injection?

1.8 Middle🔥 231 комментариев
#Архитектура и паттерны#ООП

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое Dependency Injection (DI)

Dependency Injection — это шаблон проектирования (паттерн), при котором зависимости объекта (т.е. другие объекты или сервисы, которые ему нужны для работы) не создаются внутри этого объекта, а передаются ему извне, обычно через конструктор, метод или свойство. Это разновидность инверсии управления (IoC), где контроль над зависимостями переходит от самого класса к внешнему коду.

Основная идея

Вместо того чтобы класс сам создавал свои зависимости:

class OrderService {
    private $notifier;
    
    public function __construct() {
        $this->notifier = new EmailNotifier(); // Зависимость создаётся внутри класса
    }
}

Мы передаём зависимость извне:

class OrderService {
    private $notifier;
    
    public function __construct(NotifierInterface $notifier) {
        $this->notifier = $notifier; // Зависимость внедряется извне
    }
}

Основные типы внедрения зависимостей

  1. Внедрение через конструктор — зависимости передаются при создании объекта:

    class UserController {
        private $userRepository;
        
        public function __construct(UserRepository $repository) {
            $this->userRepository = $repository;
        }
    }
    
  2. Внедрение через сеттер — зависимости устанавливаются через методы-сеттеры:

    class ReportGenerator {
        private $formatter;
        
        public function setFormatter(FormatterInterface $formatter) {
            $this->formatter = $formatter;
        }
    }
    
  3. Внедрение через свойство — зависимости присваиваются напрямую в публичные свойства (менее предпочтительный способ из-за нарушения инкапсуляции):

    class Logger {
        public $writer;
    }
    

Преимущества Dependency Injection

  • Слабая связанность — классы зависят от абстракций (интерфейсов), а не от конкретных реализаций

  • Упрощение тестирования — легко подменять реальные зависимости моками или стабами в unit-тестах:

    // Тестирование с mock-объектом
    $mockNotifier = $this->createMock(NotifierInterface::class);
    $service = new OrderService($mockNotifier);
    
  • Гибкость и переиспользуемость — можно легко менять реализации зависимостей без изменения основного кода

  • Улучшенная поддерживаемость — зависимости явно объявлены, что делает код более понятным

  • Централизованное управление зависимостями — особенно при использовании контейнера внедрения зависимостей

DI-контейнеры

В реальных приложениях часто используются DI-контейнеры, которые автоматизируют процесс внедрения зависимостей. В PHP популярны Symfony Container, PHP-DI, Laravel Container:

// Пример с Symfony Container
$container = new ContainerBuilder();
$container->autowire(OrderService::class);
$container->autowire(EmailNotifier::class);

// Контейнер автоматически разрешит зависимости
$service = $container->get(OrderService::class);

Практический пример

// Без DI - сильная связанность
class PaymentProcessor {
    private $logger;
    
    public function __construct() {
        $this->logger = new FileLogger('/var/log/app.log'); // Конкретная реализация
    }
}

// С DI - слабая связанность
interface LoggerInterface {
    public function log(string $message);
}

class PaymentProcessor {
    private $logger;
    
    public function __construct(LoggerInterface $logger) {
        $this->logger = $logger; // Абстракция вместо конкретной реализации
    }
    
    public function process(Payment $payment) {
        // Логика обработки платежа
        $this->logger->log("Payment processed: " . $payment->getId());
    }
}

// Теперь можно легко менять реализацию логгера
$processor = new PaymentProcessor(new FileLogger('/var/log/app.log'));
// Или
$processor = new PaymentProcessor(new DatabaseLogger());
// Или для тестов
$processor = new PaymentProcessor(new NullLogger());

Dependency Injection — это фундаментальный принцип современных PHP-фреймворков и приложений, который способствует созданию чистого, тестируемого и поддерживаемого кода. Он позволяет строить архитектуру, где компоненты системы минимально зависят друг от друга, что соответствует принципам SOLID, особенно Принципу инверсии зависимостей (D).

Что такое dependency injection? | PrepBro