Зачем использовать Zend_Registry вместо паттерна Сингелтона? - PullRequest
1 голос
/ 12 сентября 2011

Почему я должен использовать Zend_Registry вместо шаблона Singleton?

Мой коллега и я недавно обсуждали это. Суть его заключалась в том, что мы должны использовать Zend_Registry для всех непротиворечивых объектов, но я хотел использовать шаблон синглтона, поскольку Zend_Registry делает то же самое, но в оболочке.

У меня проблема с таким кодом:

$list = Zend_Registry::get('database')->getList($sql);

Так как есть вероятность, что база данных отсутствует в Zend_Registry. В случае отложенной загрузки мне придется создавать собственный реестр с информацией о конкретных объектах в моей системе. Например, если база данных принимает конкретные параметры во время загрузки, она должна знать это.

Я бы вместо этого использовал getInstance, и тогда весь код находился бы в одном объекте. Имеет ли это смысл?

Ответы [ 2 ]

2 голосов
/ 15 сентября 2011

Даже если вы сформулировали свой вопрос как / или, могу ли я предложить третью альтернативу?

Я стараюсь избегать как синглетонов, так и Zend_Registry, где это возможно, поскольку они функционируют, по сути, как глобальные.,Когда сегмент кода может попасть в глобальный эфир - через вызов одиночного или глобального реестра - чтобы получить что-то необходимое, он создает скрытую - или, по крайней мере, неявную - зависимость, которая усложняет отладкуи unit-test.

Напротив, я стараюсь следовать совету внедрения зависимостей, перефразируемому как: «Дайте компоненту то, что ему нужно. Не заставляйте его находить то, что ему нужно».

Я обнаружил, что для большинства сущностей, для которых мне может понадобиться реестр / синглтон - соединения БД, регистраторы и т. Д. - я могу создать их в Bootstrap, сохранить их в реестре Bootstrap и добавить их в мои контроллеры, обычново время init() с использованием $this->getInvokeArg('bootstrap')->getResource('myResource').Только контроллеры возвращаются в Bootstrap.Затем любые модели или сервисы, которым нужны эти зависимости, передают их явно через контроллер, либо через конструктор, либо с помощью внедрения сеттера.

Гибридный подход, к которому я иногда прибегаю, состоит в том, чтобы проектировать мои классы обслуживания / модели с помощью методов получения / установки для этих зависимостей - getDbAdapter() и setDbAdapter();getLogger() и setLogger() и т. Д. Получатель лениво загружает данные из глобального реестра - будь то синглтон или Zend_Registry, генерируя исключения, когда они находятся не там, где я ожидаю.В этом смысле это похоже на то, что вы предлагаете.Это нарушает философию инъекций пуристической зависимости.Но, по крайней мере, наличие методов getter / setter явно демонстрирует наличие зависимости и позволяет мне ее макетировать или предоставлять реализации не по умолчанию.

1 голос
/ 12 сентября 2011

Это для простого блога или чего-то еще. В противном случае вы застряли только с одним экземпляром БД. И это НЕ то, что вы хотите в долгосрочной перспективе. Возможно, вы захотите подключиться к другому серверу (чтобы регистрировать ошибки на центральном БД, импортировать продукты от кого-то, ...) или подключиться как другой пользователь (из соображений безопасности - вы не хотите, чтобы ваш API имел доступ к таблице admin_users, но вам все равно нужно подключиться к нему, чтобы проверить, является ли пользователь в первую очередь действительным).

Вы можете делать одноцелевые регистры (My_Db_Admin, My_Db_ReadOnly, ...), но это не имеет большого смысла для меня. Используя реестр, вы не застряли с одним экземпляром. Вы можете создать один внешний реестр и поработать с ним некоторое время, а затем удалить его;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...