Ответ 1
[Прежде чем начать, позвольте мне сказать, что я в основном программист на Java - всего лишь немного знаний PHP. Но я просто попытаюсь использовать самые важные понятия без специфики языка.]
Инъекция зависимостей основана на двух частях кода:
- Строительство
- Выполнение
В самой экстремальной форме нет операторов new
, которые можно найти в части Execution. Все они перемещаются в конструкцию. (На практике это будет уменьшено.)
Вся конструкция происходит - в строительной части. Он создает график объектов, необходимых для выполнения снизу вверх. Поэтому допустим, что он должен построить A:
- A зависит от B и
- B зависит от C.
Тогда
- C построено первым.
- Тогда B строится с C как параметром.
- Тогда A строится с B как параметр.
Таким образом, C не нужно передавать как параметр конструктора в A. Этот небольшой пример недостаточно иллюстрирует, насколько это уменьшает количество объектов, которые должны быть переданы на довольно небольшое число.
Сам инжектор зависимостей не должен передаваться в часть выполнения. Это одна из основных ошибок, которые каждый (включая меня) пытается сделать, когда они впервые вступают в контакт с ДИ. Проблема в том, что это полностью размывает линии между строительством и исполнением. Другой способ сказать, что это нарушит Закон Деметры. Или в шаблоне говорят: он в конечном итоге "деградирует" шаблон "Зависимость впрыска" к шаблону "Локатор службы". Это спорно, если это действительно деградация, но в любом случае это, как правило, не очень хорошая идея, чтобы злоупотреблять Dependency Injector как локатор.
Поэтому всякий раз, когда вам нужно дать одному из ваших построенных объектов возможность создавать другие объекты во время выполнения, вместо передачи инжектора зависимостей, вы будете передавать только простые провайдеры (термин, используемый средой Java DI Guice). Это довольно простые классы, которые могут создавать только определенный объект. Они имеют сходство с factory.
Сначала попробуйте передать необходимые зависимости непосредственно конструктору.
Итак, подведем итог:
- Создание объектов снизу вверх.
- Выполнять только несколько зависимостей, необходимых для создания объекта.
- Как только вы закончите, начните выполнение.
- Во время выполнения вы можете получать новые созданные объекты с помощью Провайдеров.
Но не заходите слишком далеко: простые объекты могут быть созданы без провайдера: -)
И теперь все, что вам нужно сделать, это перевести этот материал в качественный код. Возможно, другие могут помочь вам с несколькими примерами PHP.
Добавление: Немного больше о Провайдерах
Как отмечалось выше, понятие "поставщик" (специализированный factory) является немного специфичным для платформы Java DI Guice. Эта структура может автоматически создавать Провайдера для любого типа объекта. Однако эта концепция, как правило, полезна для DI. Единственное различие заключается в том, что без помощи Guice или аналогичной структуры вам придется сами писать Провайдеры, но это довольно легко:
Скажем, B зависит от C.
- Если B просто нужен один фиксированный экземпляр C, тогда вам не нужен провайдер - вы можете просто построить B с аргументом конструктора C.
- Если B нужно создать больше экземпляров C во время выполнения, просто напишите класс
CProvider
с помощью методаget()
, который может создать новый экземпляр C. Затем передайте экземплярCProvider
в конструктор B и сохраните Поставщик в поле экземпляра B. Теперь B может вызватьcProvider.get()
, когда ему нужен новый экземпляр C.
Поставщики являются частью кода строительства, поэтому вам разрешено использовать new C(...)
! С другой стороны, они не являются частью кода Execution, поэтому у вас не должно быть никакой логики выполнения.
CProvider
можно, конечно, передать в несколько конструкторов. Вы также можете написать несколько версий CProvider1
, CProvider2
,... - где каждый может создавать разные версии объектов C с разными свойствами. Или вы просто создаете экземпляр CProvider
несколько раз с разными аргументами.