2010-03-27 4 views
6

Вы найдете Zend_Registry?Zend_Registry: примеры реальной жизни

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

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

+3

Вы должны отличать 'Zend_Registry' от' Zend_Registry :: getInstance() '-singelton. Сам класс используется внутри ZF, не будучи глобальным, поэтому «Zend_Registry'! = Global. – chelmertz

ответ

9

Цитирование PoEAA on Registry Pattern:

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

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

  • Zend_Cache, Zend_Translate, важных приложений путей и т.д.

Однако так же, как и с Одиночки, реестр часто нахмурился. Вот article by Brandon Savage with some thought about why not to use the Registry. Основные аргументы против реестра являются

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

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

См. Это article by Martin Fowler about ServiceLocator vs. Dependency Injection.

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

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

10

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

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

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

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


Несколько реальных жизненных примеров может быть:

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


В конце концов, я нахожу Zend_Registry полезным?

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

Но если его использование можно избежать, это могло бы быть лучше: концептуально говоря, не имея ваши классы зависят от любого глобального состояния лучше: легче повторно использовать, легче проверить, ...
О том, вы можете взглянуть на то, что Dependency Injection есть.

+0

Не $ front-> setParam инъекции зависимостей? Как насчет ресурсов приложения Zend? – takeshin

4

Я согласен с Pascal MARTIN. Я только начал приучать себя к Injection Dependency. Но я не нашел способ вводить объекты в контроллеры, поэтому недавно я использовал реестр для доступа к службе в контроллере. В данном проекте я делаю следующее:

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

// 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(); 
} 

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

+0

Реестр действительно нужен здесь? Помощника по действию будет недостаточно? – takeshin

+0

Что я обычно делаю: _initMediaService() {return $ service;} ;, затем в контроллере действий: $ front-> getParam ('mediaService'); – takeshin

+0

Помощник в действии - хороший вариант, я думаю. Это ... до тех пор, пока это необходимо только в контроллере. Но у вас может быть ситуация, когда эта услуга необходима на другом уровне обслуживания или бизнеса. Я думаю, что это может быть вызвано конструкторской инъекцией. Хм ..Я не думал об этом слишком много, но, как вы можете видеть. Пока этот пример соответствует моим целям. Наверное, есть много способов решить задачу. Все зависит от того, сколько пуристов подходит к вам, я хочу догадаться. Как только я впишусь в DI немного больше, я, вероятно, откажусь от этого подхода. –