tags:

views:

51

answers:

1

I am starting to use decorators in PHP more often these days to modify an object's behavior at run-time. My problem is primarily one of laziness, we have many legacy classes with tons of methods and the thought of having to re-write/override all of them for each decorator class makes me sad. Does anyone know of a command line utility that exists that would write these decorators for me?

Or maybe there's a better way to go about this?

+1  A: 

From the question I understand you are too lazy to add the other methods, e.g. those that do not modify the decorated instance. For this purpose, you can use use the magic method __call

public function __call($method, $args) {
    return call_user_func_array(
        array($this->decoratedInstance, $method),
        $args
    );
}

You can also add __callStatic, __get and __set as needed. But note that the magic interceptors always incur some performance penalty. If you have a lot of nested decorators, this might be noticable. When in doubt, benchmark.

Gordon
Hey Gordon, yes you're right, it's the ones I'm not modifying that it'd be nice to avoid writing. Thanks. I've tried something along those lines, the problem is that since the decorator is a subclass of whatever class you're decorating, the method being called already exists (i.e. it exists in the parent class) so __call() isn't getting executed.
owise1
@owise1 That's a weird [decorator](http://sourcemaking.com/design_patterns/decorator) then. But anyway, if the class is a subclass, I dont see the problem? Just use your IDE of choice and override what you need to override. Everything else can stay as it is since it will be called from the parent class then.
Gordon
Thanks Gordon, I think you've helped me see the error in my ways. The decorator doesn't necessarily have to be a subclass of the main class. I was under the impression that's just how you did it, for type checking reasons (the decorated object still "looks like" the original object). But programming to an interface is perfect , so I can use __call().
owise1
btw, the subclassing was causing problems. When the original object holding all the correct instance variables was decorated, and a method was called that was not overridden and therefore passed to the parent class, that parent class did not have the instance vars it needed to return the right value. But no matter, that's just because I was doing it wrong to begin with, thanks @Gordon!
owise1
@owise1 you're welcome
Gordon