Class: PEAR_Delegator
Source Location: /PEAR_Delegator-0.1.0/Delegator.php
Base class for objects that allow delegation.
Author(s):
|
|
|
Inherited Variables
|
Inherited Methods
|
Class Details
[line 239]
Base class for objects that allow delegation. Introduction It is first necessary to discuss the role of delegates in PEAR. With the advent of PHP 5, a whole host of new programming techniques were introduced. Among them were class interfaces. These interfaces provide much of the benefits of multiple inheritance (with regard to methods) without adulterating the inheritance hierarchy. That is, an object can inherit from a parent class as usual, but still possess methods that qualify it as a member of another group of objects, related by certain behavior but still exclusively separate in the hierarchy. The interfaces, however, only define the protocol to which each adopting class must adhere, but they do not define the implementation. This is very useful in many instances, but for some purposes, the implementation remains viritually the same for all adopting parties. This is where delegation enters. A delegate is a class that defines methods which are intended to be called by an adopting object as if they were members of that object. For instance,
{
public function _construct()
{
parent::_construct();
}
public function _destruct()
{
parent::_destruct();
}
}
$foo = new Foo();
$foo->bar() //This results in a runtime error,
//Foo has no such method.
//Now define a delegate
class Delegate
{
public function _construct()
{
parent::_construct();
}
public function _destruct()
{
parent::_destruct();
}
public function bar()
{
echo 'bar';
}
}
foo->addDelegate(new Delegate); //add the delegate.
foo->bar(); //This will be called as if it
//were a member of Foo.
There are two types of delegates: true delegates and false delegates. True Delegates These delegates are designed to be used as delegates. As such, they follow an explicit delegate protocol. To simulate an actual method call, the forwarding mechanism transparently inserts a reference to the calling delgator as a the first argument. Consquently, such a delegate's method signatures must be of the form: accesslevel function functionName($owner, ...);
Note: - $owner can be any suitable variable name.
- $owner is unncessary if the method takes no variables and does not
access the delegator.
- The user of the method need only consider those parameters that
follow the $owner argument.
Delegates of this kind are the default. However, the argument true can be passed to explicitly denote the following list as a set of true delegates:
//or
$delegator->addDelegate(true , $delegate1, $delegate2, ... );
False Delegates These delegates are designed without any intention to be used as delegates. In essence, these are regular objects in themselves that would be useful as delegates. They have no knowledge of delegators and no reason to access a forwarding delegator. Consequently, such a delegate's method signatures are not guaranteed to be of the forme described above. Their signatures can be of any form, but they will not have access to the calling delegator. Delegates of this kind must be explicitly denoted by passing a false as the preceding argument to a list of false delegates: $delegator->addDelegate(false , $delegate1, $delegate2, ... );
Indeed, a mixed list of delegates can be called: $delegator->addDelegate($delegate1, $delegate2, false , $delegate3, $delegate4, true $delegate1 ... );
Mixed Delegates Since delegates can themselves can be delegators, the two kinds of delegates can be mixed. This is achieved by creating a true delegate that has added to it a false delegate. Then, any delegator can make calls to true delegate methods and false delegate methods through the same delegate.\ There are two further categorizations: class delegates and instance delegates. Class Delegates These delegates are classes whose methods are to be called statically. Instance Delegates These delegates are instances of classes. Delegate Hierarchies One of the benefits of this scheme is the ability to have delegate hierarchies. That is, a delegator could have a delegate that is a delegator, and the PEAR_Delegator class recognizes this by viewing such delegates as subdelegates, treating such subdelegates as subclasses would be treated. This allows for such capabilities as pseudo-overriding: //In our Foo class we could define a bar() method as follows:
public function bar()
{
//Note that it may be better to call $this->getDelegateForMethod()
//instead of $this->hasDelegate(), since the latter may forward
//the call to a delegate that does not respond.
echo 'foobar';
}
Now, the delegate's implementation would be called as well. This of course means that you can also completely override the delegate method, and not even call it. Traditional Delegation In truth, this mode of delegation is unorthodox. The traditional model of delegation is that an object delegates selected methods, calling its own version unless one delegate is present. This feature is, in fact, a subset of the scheme presented here. In otherwords, you can achieve the same effect by pseudo-overriding as described above. Implementation - Performance Impact
In actuality, there should be little extra overhead after the first call to a delegated
method. This is due to a caching scheme: When methods are called upon a
delegator, the delegator checks an associated array that contains method names as
keys and the proper delegates as values. If the key (method name) is cached
in this manner, then the method is immediatly invoked on the proper delegate. If it
does not exist, then each delegate is searched until one that can respond is found
and this relationship is cached, otherwise, a fatal error is produced. Thus no
matter how many delegates a class has, all calls after the first should
only have a small latency.
Note: Subdelegators cache their own delegates, so calls are passed down the hiearchy
until the implementing delegate handles the call.
- Flexibility of Errors.
This is not a trouble at all. In fact, the error output of this class is more direct in
many cases than PHP's own error output. It will give you the file and line of the error
in user code and its messages are modeled after those of PHP.
Terminology - owner : a delegator.
- subdelegate : A delegator that is a delegate.
- native delegate : A delegate that is an immediate delegate, not a delegate
of a delegate.
- class delegate : A delegate that is simply the class.
- instance delegate : A delegate that is an instantiated class.
Class Variables
Method Detail
__construct (Constructor) [line 270]
PEAR_Delegator __construct(
)
|
|
Constructs a delegator.
__destruct (Destructor) [line 283]
Destroys a delegator. When a delegator is destroyed, it automatically removes all of the delegates, so it is unnessary for user code to do so.
addDelegate [line 321]
void addDelegate(
$delegate, mixed
$delegate,...)
|
|
Adds delegates to the calling object. This method takes a list of classnames or objects. If an argument is a classname, then the method determines if it is defined. If it is, the class is added as a static delegate, otherwise a fatal error is raised. If it is an object, it is stored as a delegate; thus, there are two types of delegates: static and dynamic delegates.
Parameters:
addExtensions [line 295]
Add extensions to every new delegator. This loads the extensions and gives every new delegator the extensions. Delegators created before this call can be passed in to have the extensions added to them;
cacheMethod [line 849]
void cacheMethod(
string
$method)
|
|
Stores the relationship between method names and delegates. Takes a method name, searches for the delegate that can handle it, and stores the relationship in the _method_map array. This method is called when the __call() method reveives an unrecognized method. This caching of methods speeds up delegation. If the method cannot be handled by any of the adopted delegates, then an Exception is thrown. Note: This caches the first responding delegate. This is an internal method and should not be invoked.
Parameters:
filterMethodMapWithDelegate [line 655]
array filterMethodMapWithDelegate(
object
$filterDelegate)
|
|
Removes the unwanted entries from _method_map. This method cleans the _method_map array when a call to removeDelegate*() is made.
Parameters:
forwardMethod [line 872]
void forwardMethod(
string
$method, [string
$args = array()])
|
|
This can be used by delegators for pseudo-method-overriding a method. This is the public interface to the __call() method, and it allows for a method to be forwarded to the delegation system, so that pseudo-method-overriding can occur.
Parameters:
getAllDelegates [line 382]
array &getAllDelegates(
)
|
|
Gets the associated array of delegate classes => delegates. Note: Cloning may not work after this.
getDelegate [line 423]
array getDelegate(
class
$classname1)
|
|
Gets the delegate objects that are instances of the specified class. This method returns instances of the specified classname as well as child instances of the specified classnames, including subdelegates, which are native to the caller. That is, if one of the delegates is a delegator and it contains a delegate of the specified type, it will be returned regardless of its own class type.
Parameters:
getDelegateExact [line 479]
array getDelegateExact(
class
$classname1)
|
|
Gets the delegate object that is an instance of the specified class. This method returns classes of the specified type. This does not return subdelegates. That is, it uses only the actual class structures.
Parameters:
getDelegateForMethod [line 532]
array getDelegateForMethod(
$method1, string
$method1,...)
|
|
Gets the native delegate objects that respond to a certain method. The method returns delegates native to the calling delegator, which can respond to the method in question, whether it be defined in the native delegate or in a delegate deeper in the hierarchy.
Parameters:
hasDelegate [line 592]
bool hasDelegate(
[mixed
$specifier = null])
|
|
Determines whether or not the calling object adopts a particular delegate. This returns the availability of a delegate, including subdelegates.
Parameters:
hasDelegateExact [line 564]
bool hasDelegateExact(
[class
$specifier = null])
|
|
Determines whether or not the calling object adopts a particular delegate. This returns the availability of a delegate not including subdelegates. Note: This should be used for delegates that don't use hierarchies.
Parameters:
is_a [line 745]
bool is_a(
mixed
$specifier, class
$classname)
|
|
Determines if a class or instance object is of the given type. This method is an extension of the is_aExact() method. It also handles subdelegates, so it returns true if a delegator is passed in and has a delegate of type $classname, whether or not the delegator is of type $classname.
Parameters:
is_aExact [line 717]
bool is_aExact(
mixed
$specifier, class
$classname)
|
|
Determines if a class or instance object is of the given type. This method is analogous to the is_a() method of PHP. However, it handles classes too.
Parameters:
method_exists [line 797]
bool method_exists(
mixed
$specifier,
$method, class
$classname)
|
|
Determines if a class or instance object responds to a method. This method is an extension of the method_existsExact() method. It also handles subdelegates, so it returns true if a delegator is passed in and has a delegate that can implement $method, whether or not the delegator can implement the $method.
Parameters:
method_existsExact [line 770]
bool method_existsExact(
mixed
$specifier,
$method, class
$classname)
|
|
Determines if a class or instance object responds to a method. This method is analogous to the method_exists() method of PHP. However, it handles classes too.
Parameters:
removeAllDelegates [line 634]
void removeAllDelegates(
)
|
|
Removes all delegates. This completely cleans the calling object of any delegates.
removeDelegate [line 689]
void removeDelegate(
$specifier, mixed
$specifier,...)
|
|
Removes the specified delegate. Takes a list of delegate classnames and delegate objects and removes them from the calling object.
Parameters:
respondsToMethod [line 826]
bool respondsToMethod(
string
$method)
|
|
Finds whether or not the object or one of its delegates implements a method Finds whether or not the calling object can perform the given method name. The calling object can perform the given method if it or one of its delegates can do so. This means that it also searches delegates that are themselves delegators.
Parameters:
setDelegate [line 365]
void setDelegate(
mixed
$delegate)
|
|
Sets the delegator's one delegate. This method takes a classname or an object and makes it the only delegate. In actuality, it removes all of the delegates and then adds the specified delegate. This is useful for using the delegation method for the traditional delegate model.
Parameters:
__call [line 895]
mixed __call(
string
$method, [string
$args = array(null)])
|
|
Processes unrecognized method signatures. This checks the _method_map array for a cached relationship between the method and any delegate. If one exists, the method is immediately called and the result returned. If it does not, then it calls the cacheMethod() method to find and cache the method, after which is calls the unrecognized method on the proper delegate or kills the PHP with an error. This is an internal method and should not be invoked.
Parameters:
Documentation generated on Mon, 11 Mar 2019 14:31:29 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.
|
|