Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Zend_Registry: real life examples

Do you find Zend_Registry useful?

For which tasks it should be used? For which not?

Global state for variables is not a good practice. Main objects may have global state injected via $front->setParam('paramName', $object), so what's the purpose of Zend_Registry?.

like image 483
takeshin Avatar asked Mar 27 '10 22:03

takeshin


3 Answers

Quoting PoEAA on Registry Pattern:

When you want to find an object you usually start with another object that has an association to it, and use the association to navigate to it. Thus, if you want to find all the orders for a customer, you start with the customer object and use a method on it to get the orders. However, in some cases you won't have an appropriate object to start with. You may know the customer's ID number but not have a reference. In this case you need some kind of lookup method - a finder - but the question remains: How do you get to the finder?

The main reason why I use the registry (when I use it) is because it creates an easily accessible application scope. With the registry, I don't have to litter objects all over the global scope; only the Registry itself is global. It's convenient to lookup whatever I've thrown into the Registry from everywhere, including the model:

  • Zend_Cache, Zend_Translate, important applications paths, etc

However, just like with Singletons, Registry is often frowned upon. Here is an article by Brandon Savage with some thought about why not to use the Registry. The main arguments against the Registry are

  • it makes unit-testing harder
  • inexperienced coders might throw too much into it and don't care about proper design

Those who vote against the Registry usually advocate the usage of Dependency Injection, although it should be noted that you can inject the Registry as well once you got an instance of it. You do not have Inversion of Control then though, because the using object will pull what it needs from the Registry. Using the Registry as a Service Locator is a valid approach though.

See this article by Martin Fowler about ServiceLocator vs. Dependency Injection.

Like pointed out in the comments to your question, Zend_Registry is not a strict Singleton. You can instantiate multiple instances where needed in addition to using the global instance you get with Zend_Registry::getInstance(). So objects can have their own registry. But when using Registry this way, it's basically just a glorified ArrayObject.

Final note: just like with all Design Patterns, use it if applicable to your problem.

like image 185
Gordon Avatar answered Sep 30 '22 11:09

Gordon


When you are using $front->setParam, you are defining a parameter in the Front Controller.

But that parameter is not available in (or should not be used from) other layers of the application, such as the Model.

Zend_Registry, like any other global variable, is available from anywhere in your application -- including inside the Model.

But using a Registry instead of a bunch of global variables ensures you won't have many global variables everywhere : even if using a Registry implies some global state (which is not that good, one should say), it's better to have that all in one place.


A couple of real life examples could be :

  • Store the connection to the database, which is established in the bootsreap, but used in the Models
  • Globally store an adapter (or any mecanism) that will be used to do translations / localisation in all layers of your application -- Zend Framework itself does that.


In the end, do I find Zend_Registry useful ?

Well, when it comes to having some global state, yes, it's useful.

But if it's usage can be avoided, it might be better : conceptually speaking, not having your classes depend on any global state is better : easier to re-use, easier to test, ...
About that, you might want to take a look at what Dependency Injection is.

like image 39
Pascal MARTIN Avatar answered Sep 30 '22 11:09

Pascal MARTIN


I agree with Pascal MARTIN. I just started accustoming myself to Dependency Injection. But I haven't found a way to inject objects in controllers, so what I recently did was use de registry to access a service in the controller. In a current project I'm doing the following:

bootstrap:

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

...then in a controller:

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

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

Hopefully this is a useful example for you.

like image 27
Decent Dabbler Avatar answered Sep 30 '22 12:09

Decent Dabbler