Singleton vs Registry
Moderator: General Moderators
Singleton vs Registry
I am building a framework, and I am trying to decide which route to take.
In the past I have set up objects that are reused often, like a database class for instance, as a singleton. That way it is only instantiated once, and is only actually instantiated if it needs to be used. However, I have also been experimenting with building factories to return the object depending on a setting in a config file. So, this means extra processing every time the database is instantiated.
This now lends me to think that a registry class might be a better alternative, instead of having all these singletons. The object would always be instantiated, but at least the processing of the factory would only take place the one time.
Another though. Wouldn't the registry class be easier to keep track of, especially with debugging?
I'm really interested to hear your input. I am just learning about this all alone in the dark.
In the past I have set up objects that are reused often, like a database class for instance, as a singleton. That way it is only instantiated once, and is only actually instantiated if it needs to be used. However, I have also been experimenting with building factories to return the object depending on a setting in a config file. So, this means extra processing every time the database is instantiated.
This now lends me to think that a registry class might be a better alternative, instead of having all these singletons. The object would always be instantiated, but at least the processing of the factory would only take place the one time.
Another though. Wouldn't the registry class be easier to keep track of, especially with debugging?
I'm really interested to hear your input. I am just learning about this all alone in the dark.
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
Re: Singleton vs Registry
Yes, yes, yes ... Registry! You have learned the hard was some of the problems of the Singleton. There are a very few places where Singleton makes sense, but you should really know that you want/need it.thecowboy wrote:This now lends me to think that a registry class might be a better alternative, instead of having all these singletons. The object would always be instantiated, but at least the processing of the factory would only take place the one time.
Another though. Wouldn't the registry class be easier to keep track of, especially with debugging?
A Registry allows you to invert dependencies and inject object into your classes with a standard interface. It is testable and mockable.
(#10850)
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
The Registry doesn't need to be a Singleton. If you are going to access it statically throughout your application then it can be a Singleton but then you have the problems of using a static. I prefer to have a Front Controller pass the Registry object to the Action controllers. I just pass it through so it is a true object. I know others like to use statics ... that preference is up to you.
(#10850)
- feyd
- Neighborhood Spidermoddy
- Posts: 31559
- Joined: Mon Mar 29, 2004 3:24 pm
- Location: Bothell, Washington, USA
I say avoid statics at all costs. Statics are a lazy way of passing the information, just as ob_start() is a lazy way of getting rid of (hiding, actually) "headers already sent errors."
- Maugrim_The_Reaper
- DevNet Master
- Posts: 2704
- Joined: Tue Nov 02, 2004 5:43 am
- Location: Ireland
Having the Registry as a singleton is very common, though it's not the best of practices. I could use two or more Registry instances in an application since it often counts as "Global" data and there's little point handing a Registry with a set of, say configuration objects, to a family of classes which only use a collection of Line objects. Having too many objects spread across application areas where they are never intended to be used isn't always a good idea.
Notably, a Registry should just be the same one (or two) instances always. This is often the Singleton motivation, but you can do the same by watching your startup logic (only create the one Registry) and then using type hinting to ensure other classes are passed a Registry instance correctly. Passing as parameter also avoids littering your source code with the classname of the Registry which can cause lots of editing down the line for reuse.
Notably, a Registry should just be the same one (or two) instances always. This is often the Singleton motivation, but you can do the same by watching your startup logic (only create the one Registry) and then using type hinting to ensure other classes are passed a Registry instance correctly. Passing as parameter also avoids littering your source code with the classname of the Registry which can cause lots of editing down the line for reuse.
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
Exactly. This is one confusion about the Singleton. Usually when you only want one copy of and object -- you just only create one. That's the norm.
With a Front Controller and Registry it becomes pretty easy to not use Singletons because you put objects into the Registry before dispatch and then use them. It is a structural solution. You are creating a structure where you don't need a Singleton ... which is one of the goals.
With a Front Controller and Registry it becomes pretty easy to not use Singletons because you put objects into the Registry before dispatch and then use them. It is a structural solution. You are creating a structure where you don't need a Singleton ... which is one of the goals.
(#10850)
- Maugrim_The_Reaper
- DevNet Master
- Posts: 2704
- Joined: Tue Nov 02, 2004 5:43 am
- Location: Ireland
You could - in the Zend Framework you technically do not require a Registry, since the Front Controller can store a list of named objects to be passed to the Dispatcher and Action Controllers. This is sort of a hidden structure though - it's possible because the Action Controller has no defined Registry dependency and the Controller is easily subclassed so you can assign the parameter objects to private fields (one of the advantages of having an Application specific Action Controller subclass).
In most cases, having a Registry is not a problem. Once it follows a predictable interface it can be passed around like any parameter value. I suppose the danger is simple overuse. A Registry is commonly accessible from lots of places. If you're not careful it can break the separation between application layers - for example if you stick both a Session object and a User object into a Registry, and then pass it to the View (where User data is needed), it's possible a template author could misuse sessions. That's not too far fetched considering web designers and developers may not be from the same team or even company...
In most cases, having a Registry is not a problem. Once it follows a predictable interface it can be passed around like any parameter value. I suppose the danger is simple overuse. A Registry is commonly accessible from lots of places. If you're not careful it can break the separation between application layers - for example if you stick both a Session object and a User object into a Registry, and then pass it to the View (where User data is needed), it's possible a template author could misuse sessions. That's not too far fetched considering web designers and developers may not be from the same team or even company...
That was my thoughts.
I was also curious in what the difference between:and just plain old
I can understand using the registry as a container for many objects, should there be a dependency on all those objects, maybe.
Thus far I've not really needed a registry, nor singleton, as I haven't found a justifiable use for either over just passing the required dependencies between objects.
Perhaps if the chain of command gets long enough, and let's say for example, the 5th tier needs an object that is not needed by the 2nd, 3rd, nor 4th tier - but those tiers also have dependencies not required elsewhere, a registry would be good to pass around.
I think I just answered my own question..
I was also curious in what the difference between:
Code: Select all
$data = new DBObject();
$registry->add($data);
$someObject = new SomeOtherObject($registry);Code: Select all
$someObject = new SomeOtherObject($data);Thus far I've not really needed a registry, nor singleton, as I haven't found a justifiable use for either over just passing the required dependencies between objects.
Perhaps if the chain of command gets long enough, and let's say for example, the 5th tier needs an object that is not needed by the 2nd, 3rd, nor 4th tier - but those tiers also have dependencies not required elsewhere, a registry would be good to pass around.
I think I just answered my own question..
- Maugrim_The_Reaper
- DevNet Master
- Posts: 2704
- Joined: Tue Nov 02, 2004 5:43 am
- Location: Ireland
Both examples are equally valid - both offer a means of injecting objects into new objects. The Registry is more of a container though, and it ensures that the objects it holds are variable - no strict control over what must or must not be added. In a way it's a Parameter Object, a common refactoring to combat the long parameter list code smell. Not the exact same, but it bears a resemblance.I can understand using the registry as a container for many objects, should there be a dependency on all those objects, maybe.
A Registry doesn't know or care about what objects (as if can't also hold scalarsI can understand using the registry as a container for many objects, should there be a dependency on all those objects, maybe.
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
Yes ... ZF has become a bit of a mess I think, in that they have sacrificed purity for features too early in the process. I think keeping it simpler through 1.0 would be a better choice. Several parallel system have crept into the codebase e.g. static Registry, injected Registry object, injected "named" object, etc. But they are pleasing everyone!Maugrim_The_Reaper wrote:You could - in the Zend Framework you technically do not require a Registry, since the Front Controller can store a list of named objects to be passed to the Dispatcher and Action Controllers. This is sort of a hidden structure though - it's possible because the Action Controller has no defined Registry dependency and the Controller is easily subclassed so you can assign the parameter objects to private fields (one of the advantages of having an Application specific Action Controller subclass).
It is my opinion that having to pass the registry reduces its global nature and forces the programmer to choose where they want to expose that interface/functionality. It the long run I believe that will produce more modular and testable code than being able to access the Registry from anywhere.Maugrim_The_Reaper wrote:In most cases, having a Registry is not a problem. Once it follows a predictable interface it can be passed around like any parameter value. I suppose the danger is simple overuse. A Registry is commonly accessible from lots of places. If you're not careful it can break the separation between application layers - for example if you stick both a Session object and a User object into a Registry, and then pass it to the View (where User data is needed), it's possible a template author could misuse sessions. That's not too far fetched considering web designers and developers may not be from the same team or even company...
(#10850)
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
In some ways I think it is more an artifact of certain architectures -- specially controller architectures. If you find that all your "actions" need request, response, config, session, outer view, etc. objects then you gravitate toward a solution to hold all of them and make them available to your "actions."Jenk wrote:Thus far I've not really needed a registry, nor singleton, as I haven't found a justifiable use for either over just passing the required dependencies between objects.
Perhaps if the chain of command gets long enough, and let's say for example, the 5th tier needs an object that is not needed by the 2nd, 3rd, nor 4th tier - but those tiers also have dependencies not required elsewhere, a registry would be good to pass around.
(#10850)