2010-03-27 18 views
6

¿Le parece útil Zend_Registry?Zend_Registry: real life examples

¿Para qué tareas debería usarse? Para que no?

Estado global para las variables no es una buena práctica. objetos principales pueden haber estado global inyectada a través de $front->setParam('paramName', $object), ¿cuál es el propósito de Zend_Registry ?.

+3

Debe diferenciar 'Zend_Registry' de' Zend_Registry :: getInstance() '-singelton. La clase en sí misma se usa internamente en ZF sin ser global, por lo que 'Zend_Registry'! = Global. – chelmertz

Respuesta

9

Citando PoEAA on Registry Pattern:

Cuando usted quiere encontrar un objeto que por lo general comienza con otro objeto que tiene una asociación a la misma, y ​​el uso de la asociación para localizarlo. Por lo tanto, si desea buscar todos los pedidos para un cliente, comience con el objeto del cliente y utilice un método para obtener los pedidos. Sin embargo, en algunos casos no tendrá un objeto apropiado para comenzar. Puede conocer el número de identificación del cliente pero no tener una referencia. En este caso, necesitas algún tipo de método de búsqueda, un buscador, pero la pregunta sigue siendo: ¿cómo llegas al buscador?

La razón principal por la que utilizo el registro (cuando lo uso) es porque crea un ámbito de aplicación de fácil acceso. Con el registro, no tengo que ensuciar objetos en todo el alcance global; solo el Registro en sí es global. Es conveniente para las operaciones de búsqueda lo que he tirado en el registro de todas partes, incluyendo el modelo:

  • Zend_Cache, Zend_Translate, importantes rutas de aplicaciones, etc

Sin embargo, al igual que con Singleton, del registro es a menudo mal visto. Aquí hay un article by Brandon Savage with some thought about why not to use the Registry. Los principales argumentos contra el Registro son

  • que hace más difícil
  • codificadores inexpertos pruebas unitarias pueden tirar demasiado en él y no se preocupan por el diseño apropiado

Los que votan contra el Registro generalmente recomiendan el uso de Dependency Injection, aunque debe tenerse en cuenta que también puede insertar el Registro una vez que tenga una instancia de este. Sin embargo, no tiene Inversion of Control, porque el objeto que lo usa extrae lo que necesita del Registro. Sin embargo, usar el Registro como Localizador de Servicios es un enfoque válido.

ver este article by Martin Fowler about ServiceLocator vs. Dependency Injection.

Como se señala en los comentarios a su pregunta, Zend_Registry no es una estricta Singleton. Puede crear instancias múltiples donde sea necesario además de usar la instancia global que obtiene con Zend_Registry::getInstance(). Entonces los objetos pueden tener su propio registro. Pero al usar Registry de esta manera, básicamente es solo un ArrayObject glorificado.

Nota final: Al igual que con todos los patrones de diseño, lo utilizan en su caso a su problema.

10

Cuando está utilizando $front->setParam, que está definiendo un parámetro en el controlador frontal.

Pero ese parámetro no está disponible en (o no debe utilizarse desde) otras capas de la aplicación, como el Modelo.

Zend_Registry, como cualquier otra variable global, está disponible desde cualquier lugar de su aplicación, incluso dentro del Modelo.

Pero usar un Registro en lugar de un grupo de variables globales asegura que no tendrá muchas variables globales en todas partes: incluso si usar un Registro implica algún estado global (que no es tan bueno, debería decirse), es es mejor tener todo en un solo lugar.


Un par de ejemplos de la vida real podría ser:

  • tienda de la conexión a la base de datos, que se establece en el bootsreap, sino que se utiliza en los modelos
  • Globalmente almacenar un adaptador (o cualquier mecanismo) que se utilizará para hacer traducciones/localización en todas las capas de su aplicación, Zend Framework lo hace.


Al final, puedo encontrar Zend_Registry útil?

Bueno, cuando se trata de tener un estado global, sí, es útil.

Pero si se puede evitar su uso, podría ser mejor: conceptualmente hablando, no es mejor que sus clases dependan de ningún estado global: más fácil de reutilizar, más fácil de probar, ...
Acerca de eso, Es posible que desee echar un vistazo a lo que Dependency Injection es.

+0

¿No es $ front-> setParam la inyección de dependencia? ¿Qué pasa con los recursos de la aplicación Zend? – takeshin

4

Estoy de acuerdo con Pascal MARTIN. Acabo de empezar a acostumbrarme a Dependency Injection. Pero no he encontrado una forma de inyectar objetos en los controladores, entonces lo que hice recientemente fue usar el registro para acceder a un servicio en el controlador. En un proyecto en curso que estoy haciendo lo siguiente:

de arranque:

// 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; 

... entonces en un controlador:

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

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

suerte, este es un ejemplo útil para tú.

+0

¿El registro es realmente necesario aquí? Ayudante de acción no sería suficiente? – takeshin

+0

Lo que suelo hacer: _initMediaService() {return $ service;} ;, luego en el controlador de acción: $ front-> getParam ('mediaService'); – takeshin

+0

Ayudante de acción es una buena opción también, supongo. Eso es ... siempre que solo sea necesario en un controlador. Pero es posible que tenga una situación en la que este servicio sea necesario también en otro servicio o capa empresarial. Aunque eso podría ser solucionado por inyección de constructor otra vez, supongo. Hmm ...Todavía no he pensado demasiado en profundidad como puedes ver. Hasta ahora este ejemplo se ajusta a mis propósitos. Supongo que hay muchas maneras de lograr una tarea. Todo depende de la cantidad de enfoque de un purista que quiera tomar, supongo. Tan pronto como profundice un poco más en DI, probablemente abandone este enfoque. –