ZF-7252: Zend_Controller_Action_Interface breaks OOP convention
Description
I ran into a problem with this interface as implemented in 1.8.4 (possibly earlier), in that my test harness defines classes for each controller under test, as described in this article:
http://blog.fedecarg.com/2008/12/…
to the point, I am extending a controller and changing the constructor (and its signature) in the derived class. This is not possible with the new Zend_Controller_Action_Interface.
I know supporting this method is not the concern of ZF, but the new interface does break this approach. The larger problem is that it breaks general OOP design principles, in that derived classes should be free to instantiate themselves however they see fit. With the new interface, ANY class implementing Zend_Controller_Action_Interface - INCLUDING any class that extends Zend_Controller_Action - must have that constructor signature. This just seems wrong. In fact, I found much supporting arguments for all sorts of OO languages when doing a quick google search on this subject: http://google.com/search/?q=interface+constructor
This is my first ZF ticket, so I apologize for not having a lot of the history here. But I hope this causes some second thoughts about placing constructors in the interface, thereby enforcing needless constraints on any derived classes.
Comments
Posted by Matthew Weier O'Phinney (matthew) on 2009-07-13T15:12:35.000+0000
Actually, changing the signature of a method via an extending class raises PHP errors as well -- this has nothing to do with the interface.
You can add additional arguments to a method signature, provided they have default values. But removing an argument or using a different variable name or type breaks encapsulation.
While I understand your arguments about not requiring a constructor within an interface, there are some good reasons to do so as well -- if the classes that would normally instantiate the object -- for instance, a factory -- will be passing specific arguments, the signature must be defined in such a way that will allow them.
You can mimic the behavior by having explicit setters for the objects that need to be passed to it.
Now, all of this is a moot point. In this particular instance, the interface was defined after the abstract class was in existence, and we merely designed it to mimic Zend_Controller_Action.
We can refactor when we approach 2.0, but for now, I'm closing this issue as "Won't Fix", as changing it would break BC and the expectations of classes implementing the interface.