The challenge of "never use extend" is that simply wrapping classes in 
decorators only goes so far.  You can't always maintain interface compliance 
if you're nesting decorators, and if you're overriding only one out of a dozen 
or two methods then you have a lot of foo() { return $obj->foo(); } method 
implementations.  Aside from being hard to read, that also eats up cycles for 
the extra stack calls.  __call() can make it much less code but is also much 
slower.

If there were a syntactic-level support for "wrap this object in this class 
and pass through any method that isn't redefined", a sort of sideways extends, 
that would become much simpler.  I'm not sure what that would look like, 
though.

Or perhaps this is a good time to revisit the traits proposal from a few 
months back?

--Larry Garfield 

On Monday 15 March 2010 12:36:32 pm Hector Virgen wrote:
> I also ran into this problem with Zend_Db_Select. I wanted to add a new
> constant to improve my usage of Zend_Db_Table#select(), but that method
> would always returns an instance of Zend_Db_Table_Select which extended
> Zend_Db_Select. There was no easy way for me to add my class constant
> without resorting to one of the 3 methods Chris mentioned.
> 
> Another possible solution (although it would require a rewrite of the
> framework classes) is to avoid using "extends" entirely. This can be
> accomplished by using interfaces instead, which is explained in this
> article:
> 
> http://www.javaworld.com/javaworld/jw-08-2003/jw-0801-toolbox.html
> 
> Although the article is a bit dated and it's for Java, the concept still
> applies and can help developers make better use of framework code by
> inheriting only the implementations they need while providing alternate
> implementations when necessary.
> 
> Maybe this can be a design paradigm to attempt to follow in ZF 2.0?
> 
> --
> Hector
> 
> 
> On Sat, Mar 13, 2010 at 8:10 AM, Richard Quadling
> 
> <rquadl...@googlemail.com>wrote:
> > On 13 March 2010 01:50, Chris Trahey <christra...@gmail.com> wrote:
> > > Perhaps a new concept in class-based OO programming, I'm not sure.
> > >
> > > Depending on your perspective you could call it ancestor overloading
> > > (or upstream overloading) or class underloading.
> > >
> > >
> > > We are increasingly developing with the aid of frameworks & libraries.
> > > In fact, this idea came from my current project using the Zend
> > > Framework.
> > >
> > > These libraries, while greatly extensible, are also fairly
> >
> > self-extending.
> >
> > > That is, they include many classes that extend many classes, which is
> >
> > great.
> >
> > > As consumers of these libraries, we can extend the classes and consume
> >
> > the
> >
> > > API however we please, but there is one sticking point.
> > >
> > > We cannot change classes that many other classes extend without
> > > extending
> >
> > or
> >
> > > changing each child class and then making sure that our code uses the
> > > new class.
> > >
> > >
> > > For a concrete example, I was working with the Zend_Form_Element
> >
> > subclasses,
> >
> > > and I realized that I wanted to change some of the default behavior (in
> > > Zend_Form_Element).
> > >
> > > - at this point I will assume the reader understands why I wouldn't
> > > want
> >
> > to
> >
> > > just start changing the Zend library files -
> > >
> > > There are many subclasses of Zend_Form_Element. If you want to change
> > > the default behavior for all of them, you have 3 choices currently:
> > >
> > > 1. Directly edit the Zend_Form_Element file in the library, -bad for
> >
> > updates
> >
> > > & other projects that use the library
> > >
> > > 2. subclass Zend_Form_Element and change declaration of the descendants
> >
> > to
> >
> > > extend new class - same problems
> > >
> > > 3. extend each child class and implement those subclasses in your app
> >
> > code
> >
> > > -very tedious and TONS of repeated code, breaks consistency of API for
> > > developers.
> > >
> > >
> > > There could be a better way, if we could insert a class into the family
> > > tree.
> > >
> > > And that's the heart of this idea, so I'll repeat it:
> > >
> > > * insert a class into the family tree *
> > >
> > >
> > > Image we do it using an alternative keyword to "extends", such as
> > > "overloads".
> > >
> > >
> > > Example:
> > >
> > >
> > > class Library_Class { }
> > >
> > > class Library_Subclass extends Library_Class {}
> > >
> > > and then:
> > >
> > > class My_LibClass_Overload overloads Library_Class{}
> > >
> > >
> > > Now new instances of Library_Subclass actually extend
> >
> > My_LibClass_Overload,
> >
> > > which "extends" Library_Class. The developer would then code
> > > My_LibClass_Overload as if it were declared like this:
> > >
> > > class Library_Class {}
> > >
> > > class My_LibClass_Overload extends Library_Class {}
> > >
> > > class Library_Subclass extends My_LibClass_Overload {}
> > >
> > >
> > > But indeed the declaration of Library_Subclass would *not* have to
> >
> > change.
> >
> > > This way developers could "extend" default functionality and have
> >
> > *existing*
> >
> > > library classes pick up the new functionality without redeclaring
> >
> > anything
> >
> > > in the library.
> > >
> > > Downstream classes would still override any methods that they
> > > redeclare.
> >
> > If
> >
> > > you wanted to have end-point classes in the library have different
> >
> > behavior,
> >
> > > you would overload them instead, such as
> > >
> > > class My_LibSubclass_Overload overloads Lib_Subclass {}
> > >
> > >
> > > The benefit is that the application code can still consume "standard"
> > > classes, such as Library_Subclass and not need to know or care about
> > > the extended functionality.
> > >
> > >
> > > Going back to my concrete example, my code could then still use
> > > Zend_Form_Element_Text, but benefit from the modifications I added,
> >
> > without
> >
> > > me having to touch the library code.
> > >
> > >
> > > I hope I've explained clearly what this could look like. I'm a younger
> > > developer, so forgive me if I'm rough on the terminology -perhaps
> > > overload/underload is not the best word for this functionality. Also,
> > > I'm not sure if there are other class-based OO languages that allow
> > > this kind
> >
> > of
> >
> > > behavior... Prototypal languages perhaps, as is the case with
> > > javascript
> >
> > and
> >
> > > the Obj.prototype which (combined with anonymous functions) allows you
> > > to extend the "base" functionality of other objects that "extend" it.
> > >
> > >
> > > Thank you for your comments and thoughts!
> > >
> > >
> > > Chris Trahey
> >
> > I had exactly the same issue with Zend_Soap_AutoDiscover. This class
> > uses Zend_Soap_Wsdl to create the WSDL file for a SOAP service.
> >
> > The class was hard coded. The AutoDiscover class allowed you to supply
> > a class name to handle complex types, but not in conjunction with xsd
> > scalar types. The Zend_Soap_Wsdl class handled php -> xsd types and
> > read docblocks for that.
> >
> > But if the docblock had an xsd type (xsd:datetime, xsd:token, etc.)
> > which are used to tell the consumer what the type is, then there was
> > no way to get these in.
> >
> > So, I created this patch
> > http://framework.zend.com/code/changelog/Zend_Framework?cs=21379 (diff
> >
> > http://framework.zend.com/code/browse/Zend_Framework/standard/trunk/libra
> >ry/Zend/Soap/AutoDiscover.php?r1=20096&r2=21379 )
> > which allows me to supply an alternative class name in a similar
> > fashion to being able to supply a complex type handler class name.
> >
> > This was the easiest route I could find and the least impacting (full
> > BC exists).
> >
> > The amendment I made to allow a subclass to be used as an alternative
> > is a one off hit, so maybe this technique could be used for Zend_Form
> > (I assume this is the class you are needing to amend).
> >
> > Regards,
> >
> > Richard.

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to