Zend_Registry: примеры из жизни - PullRequest
6 голосов
/ 28 марта 2010

Считаете ли вы Zend_Registry полезным?

Для каких задач его следует использовать? Для чего нет?

Глобальное состояние для переменных не является хорошей практикой. Главные объекты могут иметь глобальное состояние, введенное через $front->setParam('paramName', $object), Так в чем же цель Zend_Registry?

Ответы [ 3 ]

10 голосов
/ 28 марта 2010

Когда вы используете $front->setParam, вы определяете параметр в Front Controller.

Но этот параметр недоступен в (или его не следует использовать) в других слоях приложения, таких как Модель.

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

Но использование реестра вместо группы глобальных переменных гарантирует, что у вас не будет много глобальных переменных везде: даже если использование реестра подразумевает некоторое глобальное состояние (что не так хорошо, надо сказать) лучше иметь все это в одном месте.


Вот пара примеров из жизни:

  • Сохранение соединения с базой данных, которое устанавливается в загрузочном буфере, но используется в моделях
  • Глобально храните адаптер (или любой механизм) , который будет использоваться для выполнения переводов / локализации во всех слоях вашего приложения - сам Zend Framework делает это.


В конце концов, я считаю Zend_Registry полезным?

Ну, когда дело доходит до некоторого глобального состояния, да, это полезно.

Но если его можно избежать, может быть и лучше: если говорить концептуально, отсутствие зависимости ваших классов от какого-либо глобального состояния лучше: проще для повторного использования, проще для тестирования, ...
Об этом, возможно, вы захотите взглянуть на то, что Внедрение зависимости .

10 голосов
/ 28 марта 2010

Цитирование PoEAA в шаблоне реестра :

Когда вы хотите найти объект, вы обычно начинаете с другого объекта, который имеет ассоциацию с ним, и используете ассоциацию для перехода к нему. Таким образом, если вы хотите найти все заказы для клиента, вы начинаете с объекта customer и используете метод для получения заказов. Однако в некоторых случаях у вас не будет подходящего объекта для начала. Вы можете знать идентификационный номер клиента, но не иметь ссылки. В этом случае вам нужен какой-то метод поиска - искатель, но остается вопрос: как добраться до искателя?

Основная причина, по которой я использую реестр (когда я его использую) , заключается в том, что он создает легкодоступную область приложения. С реестром мне не нужно засорять объекты по всему глобальному охвату; только сам реестр является глобальным. Удобно искать все, что я бросил в Реестр отовсюду, включая модель:

  • Zend_Cache, Zend_Translate, пути к важным приложениям и т. Д.

Однако, как и в случае с синглетонами, реестр часто вызывает недовольство. Вот статья Брэндона Сэвиджа с некоторыми соображениями о том, почему бы не использовать реестр . Основными аргументами против Реестра являются

  • затрудняет юнит-тестирование
  • неопытные программисты могут бросить в него слишком много и не заботиться о правильном дизайне

Те, кто голосует против Реестра, обычно выступают за использование Инъекции зависимостей , хотя следует отметить, что вы можете также внедрить Реестр, как только получите его экземпляр. Тогда у вас нет Inversion of Control , потому что использующий объект извлечет из реестра то, что ему нужно. Однако использование реестра в качестве локатора служб является верным подходом.

См. Эту статью Мартина Фаулера о ServiceLocator против внедрения зависимостей .

Как указано в комментариях к вашему вопросу, Zend_Registry не является строгим синглтоном. Вы можете создать несколько экземпляров, где это необходимо, в дополнение к использованию глобального экземпляра, который вы получаете с Zend_Registry::getInstance(). Таким образом, объекты могут иметь свой собственный реестр. Но при использовании Registry таким образом, это просто прославленный ArrayObject.

Последнее замечание: как и во всех шаблонах проектирования, используйте его, если применимо к вашей проблеме.

4 голосов
/ 28 марта 2010

Я согласен с Паскаль МАРТИН . Я только начал привыкать к инъекции зависимости. Но я не нашел способа внедрить объекты в контроллеры, поэтому недавно я использовал de Registry для доступа к сервису в контроллере. В текущем проекте я делаю следующее:

самозагрузка:

// simple DI without an IoC container, and what have you
$dbAdapter    = Zend_Db::factory( /* bla bla */ );
$mediaService = new Service_Media( new Repository_Media_Db( $dbAdapter ) );
$registry     = Zend_Registry::getInstance();
$registry->mediaService = $mediaService;

... затем в контроллере:

public function init()
{
    $this->_mediaService = Zend_Registry::get( 'mediaService' );
}

public function listAction()
{
    // simplified
    $this->view->media = $this->_mediaService->listAllUploadedVideos();
}

Надеюсь, это полезный пример для вас.

...