Даже если вы сформулировали свой вопрос как / или, могу ли я предложить третью альтернативу?
Я стараюсь избегать как синглетонов, так и Zend_Registry
, где это возможно, поскольку они функционируют, по сути, как глобальные.,Когда сегмент кода может попасть в глобальный эфир - через вызов одиночного или глобального реестра - чтобы получить что-то необходимое, он создает скрытую - или, по крайней мере, неявную - зависимость, которая усложняет отладкуи unit-test.
Напротив, я стараюсь следовать совету внедрения зависимостей, перефразируемому как: «Дайте компоненту то, что ему нужно. Не заставляйте его находить то, что ему нужно».
Я обнаружил, что для большинства сущностей, для которых мне может понадобиться реестр / синглтон - соединения БД, регистраторы и т. Д. - я могу создать их в Bootstrap
, сохранить их в реестре Bootstrap
и добавить их в мои контроллеры, обычново время init()
с использованием $this->getInvokeArg('bootstrap')->getResource('myResource')
.Только контроллеры возвращаются в Bootstrap
.Затем любые модели или сервисы, которым нужны эти зависимости, передают их явно через контроллер, либо через конструктор, либо с помощью внедрения сеттера.
Гибридный подход, к которому я иногда прибегаю, состоит в том, чтобы проектировать мои классы обслуживания / модели с помощью методов получения / установки для этих зависимостей - getDbAdapter()
и setDbAdapter()
;getLogger()
и setLogger()
и т. Д. Получатель лениво загружает данные из глобального реестра - будь то синглтон или Zend_Registry, генерируя исключения, когда они находятся не там, где я ожидаю.В этом смысле это похоже на то, что вы предлагаете.Это нарушает философию инъекций пуристической зависимости.Но, по крайней мере, наличие методов getter / setter явно демонстрирует наличие зависимости и позволяет мне ее макетировать или предоставлять реализации не по умолчанию.