Zend front controller and getInstance()

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Zend front controller and getInstance()

Post by alex.barylski »

I normally stay away singletons, unless something will literally fall apart (which I have yet to experience in PHP).

I seen this code just now:

Code: Select all

$controller = Zend_Controller_Front::getInstance();
And forced me to ask, why?

I see two possible reasons:

1. Because front controller should only ever have one instance -- hence the singleton -- is this really nessecary?
2. Because the developers anticipated it's global use and to avoid stuffing the instance in a registry they decided on giving it global access via a getInstance() method -- this is common in many Window'ing frameworks like MFC, OWL, etc. I personally think it was more for keeping with tradition than following a 'best practice'.

My own front controllers are pretty simple and would never really need to be accessed in the context of a controller/model or view which is probably why I fail to see why the use of a singleton. Do they really think component developers are going to try and create yet anotehr instance, when at the point of a controller the application is already booted up and rarin' to go?

Any one have any ideas on why they chose this approach?
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: Zend front controller and getInstance()

Post by Eran »

#2 is the clear winner. You can argue personal preference of style etc, but it does come in useful on occasion.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Zend front controller and getInstance()

Post by Christopher »

They had to make it a Singleton because several other MVC components need to access the Front Controller instance. The reason is that the Front Controller holds a lot of necessary information due to how they designed things. I think it forces some fixed dependencies that I don't like -- and causes the Zend Controller to be a little on the heavy side. But I can see from a practical point of view why they did what they did.

Pytrin and I have argued the "where stuff goes" question in Controller Architectures. I recall that we disagreed. ;)
(#10850)
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: Zend front controller and getInstance()

Post by josh »

Singletons aren't inherently evil, they're just more prone to bad design. One way to do this would be to grab the object from a registry ( singleton or injected ). In this case they probably didn't want to force the registry dependency, but I know several other components do depend on zend_registry, however
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Zend front controller and getInstance()

Post by Christopher »

josh wrote:Singletons aren't inherently evil, they're just more prone to bad design.
When they are used for the problem that they solve -- for there to be one and only one instance of an object. And the other ways to achieve that do not fit in the design. But unfortunately they are also answer to the (conscious or unconscious) urge that a global would really make this easy...
josh wrote:One way to do this would be to grab the object from a registry ( singleton or injected ). In this case they probably didn't want to force the registry dependency, but I know several other components do depend on zend_registry, however
Yeah, they didn't want that requirements because of various anti-Registry forces early in the design. Unfortunately you end up needing the Registry and having the Singletons too.
(#10850)
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: Zend front controller and getInstance()

Post by Eran »

It's really only 2-3 components.. and it wasn't a requirement really
this is what you get when you have several teams developing separately, they make sometimes different design decisions
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: Zend front controller and getInstance()

Post by alex.barylski »

I think it forces some fixed dependencies that I don't like -- and causes the Zend Controller to be a little on the heavy side.
Thats pretty much how I see things.
Singletons aren't inherently evil, they're just more prone to bad design
The concept behind singletons make a great deal of sense. Limiting an object to a single instance. The implementation and/or use of a singleton is what I usually dislike.

Code: Select all

$front = Zend_Front_Controller::getInstance()
To have that scattered all over your controller methods...would be a PITA to search & replace if the class name ever changed to Zend_Controller_Front or vis-versa. That is about the only issue I have with the use of singletons. I don't imagine Zend will change that now (anytime soon anyways) but with my own framework, where I am the only developer and user, things change at the interface level constantly, so the driving forces behind the development are quite different.
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: Zend front controller and getInstance()

Post by josh »

If you use singletons in such a way you that it could be replaced in a matter of minutes, then your design is fine in my eyes. Do you really need to change this behavior? From what I've seen Matt Phinney prefers you to create FC plugins rather then "talk" to the FC from within your application code
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Zend front controller and getInstance()

Post by Christopher »

josh wrote:If you use singletons in such a way you that it could be replaced in a matter of minutes, then your design is fine in my eyes. Do you really need to change this behavior? From what I've seen Matt Phinney prefers you to create FC plugins rather then "talk" to the FC from within your application code
Well there is no way to replace the source of information for the Action Controllers -- it is hard coded to the Zend Front Controller. It's not that they prefer plugins ... it's the only way.

I think my question is: What problem does this line of code solve?

Code: Select all

$front = Zend_Front_Controller::getInstance()
Was the problem that the needed to access a common object? Or was the problem that people were getting multiple instances of the Front Controller?
(#10850)
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: Zend front controller and getInstance()

Post by josh »

Well I'm sure theres design decisions in any framework that don't solve direct user needs, if you were a zealot I guess you could do:

Code: Select all

 
class My_Fc extends Zend_Controller_Front
public function __construct()
    {
        $this->_plugins = new Zend_Controller_Plugin_Broker();
    }
 
    public static function getInstance()
    {
        throw new Exception;
    }
 
I guess the bigger question is as long as you make the getInstance() call 1x only from your bootstrap what problems are being created that doing it differently would solve? ( besides making it easier to test which isn't that relevant here )
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Re: Zend front controller and getInstance()

Post by Jenk »

The front controller was implemented in ZF before the registry was.. so it's not as clear cut as that, they probably just thought to leave it be because frankly.. it doesn't actually matter. You'll only ever have one "front controller," and as far as my experiences go, you'll never need to use it outside of a bootstrap..
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Zend front controller and getInstance()

Post by Christopher »

josh wrote:I guess the bigger question is as long as you make the getInstance() call 1x only from your bootstrap what problems are being created that doing it differently would solve? ( besides making it easier to test which isn't that relevant here )
The static call to Zend_Controller_Front::getInstance() is a couple other places, such as in the Action Controller.
Jenk wrote:The front controller was implemented in ZF before the registry was.. so it's not as clear cut as that, they probably just thought to leave it be because frankly.. it doesn't actually matter. You'll only ever have one "front controller," and as far as my experiences go, you'll never need to use it outside of a bootstrap..
There are lots of object that you only need one of -- in fact most objects you only need one of. But Singleton solves the problem that you are getting multiple instances when you only want one. It is a very specific problem.
(#10850)
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: Zend front controller and getInstance()

Post by josh »

arborint wrote:But Singleton solves the problem that you are getting multiple instances when you only want one. It is a very specific problem.
Well that was it's intended / original solution, but it can be used to solve other problems, that doesn't make it the best decision though. Since they have a registry now it would be cleaner I guess to store the FC there, but if the registry itself is a singleton it really makes a nominal difference to your own applications design. I think the problem is less that they *have* a singleton FC, I think the problem as you, arborint, have pointed out, is that they use the singleton FC to get ahold of objects like the dispatcher from the action. I was not aware thats how they were doing it. Looks like they already have the FC dependency injected into the action controller. They should refactor, call getFrontController instead of FC->getInstance(). So I guess we are agreeing there is nothing wrong about the FC being a singleton, that is how it should stay, but it should not be used in place of globals.

Edit: looks like it does use the instance variable and only uses the getInstance() call in exceptional situations. See: http://framework.zend.com/issues/browse ... l-tabpanel
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Zend front controller and getInstance()

Post by Christopher »

josh wrote:Well that was it's intended / original solution, but it can be used to solve other problems,
Actually then it not that pattern anymore. We could create a new pattern called Static Registry of One ... but there is already a name for that ... ;)
josh wrote:Edit: looks like it does use the instance variable and only uses the getInstance() call in exceptional situations. See: http://framework.zend.com/issues/browse ... l-tabpanel
That is pretty funny. Those Zend boys like to implement workarounds for their design decisions, don't they. And the getInstance() is not just for exceptions -- check the code. That link had the funniest line of code I have seen in a very long time:

Code: Select all

$front->setParam('front', $this)
:roll:
(#10850)
Theory?
Forum Contributor
Posts: 138
Joined: Wed Apr 11, 2007 10:43 am

Re: Zend front controller and getInstance()

Post by Theory? »

How does Skeleton handle it by default?
Post Reply