Wiretap

http://www.sitepoint.com/forums/showFoo.php?p=4071343&Foocount=10<-->

A wiretap silently listens to messages between two objects.

Suppose we have:

<?php    
    
class Foo {

    function 
a() {
        ...
    }
}
?>

Foo can be wrapped in a new class, Bar, which drops straight in to the object graph in its place:

<?php    
    
class Bar {
    function 
__construct($foo) {
        
$this->foo $foo;
    }
    function 
a() {
        
$result $this->foo->a();
        
// do something
        
return $result;
    }
}

?>

Although Foo clients are now dealing with a Bar, this is completely invisible to them. The Foo object is also unaware of the wiretap. Thus a new feature can easily be added (and removed) simply by wiring up the object graph differently. None of the existing classes will need to be changed.

For example, a wiretap could allow some kind of reporter/view class to listen in to the traffic between domain objects. You could chop and change the way you report on the domain without being required to change any domain classes or their tests.

Note that a wiretap listens to messages between objects rather than some kind of internal, observable state, as in a normal Observer. However, the wiretap could query observable, if required, via the existing interface.

Often you're only interested in some of the messages being passed to an object and can ignore the rest:

<?php    
    
class Bar {
    function 
__construct($foo) {
        
$this->foo $foo;
    }
    function 
a() {
        ...
    }
    function 
__call($method$args) {
        return 
call_user_func_array(
            array(
$this->foo$method), 
            
$args);
    }
}
?>

Although a wrapper using some __call() magic does in fact implement all methods of the wrapped class, php won't see it that way. A different type is presented to clients and that could be a problem in a type-hint-aware context.

Aperiplus has a ready-rolled Wiretap class. As an example of how this might be used to report on file writes, see WriteListener.

<?php    
    
$wiretap 
= new WriteListener(
    new 
FileWriter('path/to/file'), 
    new 
ReporterThingy);

?>

The wiretap would be passed to clients of FileWriter instead of the FileWriter instance.

 

SourceForge.net Logo