2010年3月13日星期六

[fw-webservices] Re: [PHP-DEV] RFC - "class underloading" -or- "ancestor overloading"

On 13 March 2010 01:50, Chris Trahey <christrahey@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/library/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.

--
-----
Richard Quadling
"Standing on the shoulders of some very clever giants!"
EE : http://www.experts-exchange.com/M_248814.html
EE4Free : http://www.experts-exchange.com/becomeAnExpert.jsp
Zend Certified Engineer : http://zend.com/zce.php?c=ZEND002498&r=213474731
ZOPA : http://uk.zopa.com/member/RQuadling

没有评论: