Peter,

On Fri, Aug 24, 2012 at 2:36 PM, Peter Nguyen <pe...@likipe.se> wrote:

> This is exactly the "problem" that AOP solves. I think the decorator
> pattern is just a solution for the shortcoming of the language itself.


Actually, I think it's the other way around. Think about this for a second.
With the AOP functionality proposed, it applies to *all* instances of a
class. That's fine, except when you only want to add the functionality to
one instance.


> What if you want multiple advices at that joint point, do you create
> decorator on decorator, call another class inside the decorator, or use the
> observer pattern? Do you need to decorate all your classes before hand just
> to be futureproof? What do you do if you stumple upon code you need to hook
> into with no decorator?


No, you just decorate each piece of functionality onto the class. That's
the point of a decorator. You don't need to worry about it, you just wrap
whatever was there. So you can put decorator on top of decorator. You
compose the functionality in layers.

And "decorate all your classes before hand just to be futureproof?" tells
me you haven't worked with decorators much, as that's a bit of a silly
comment. You decorate to change behavior in a specific way. Let's take
a canonical example:

interface Coffee {
    public function getPrice();
}
class BlackCoffee implements Coffee{
    public function getPrice() { return 1; }
}
class Cream implements Coffee {
    protected $coffee;
    public function __construct(Coffee $coffee) {
        $this->coffee = $coffee;
    }
   public function getPrice() { return 0.25 + $this->coffee->getPrice(); }
}
class Sugar implements Coffee {
    protected $coffee;
    public function __construct(Coffee $coffee) {
        $this->coffee = $coffee;
    }
   public function getPrice() { return 0.50 + $this->coffee->getPrice(); }
}

$creamAndSugar = new Sugar(new Cream(new BlackCoffee));
$creamOnly = new Cream(new BlackCoffee);
$sugarOnly = new Sugar(new BlackCoffee);

I didn't de-deuplicate (by creating an abstract decorator) to illustrate
the concept of what's going on.

So no, you don't create a decorator for every class. You create one for
each class you need to add functionality to, when you need to add
functionality to it.

If you want to hook into code without a decorator, you write a decorator.
It's that simple.


> AOP solves this in a nice way without the need to "pollute" your code.
> Just think of the possiblities, not having to deal with
> do_action/add_action  again or to think about all the possible events that
> you need to support in your code for it to be modular. With AOP, you can
> just write your class and feel safe that there will be a way to hook into
> your methods without modifying it if you ever need to.
>

Actually, I'd argue this the AOP addition is polluting code more, because
it's always global. And global is the antithesis to flexibility (which is
the entire point of AOP after all). If it worked on a per-object level, I
could see that argument. But seeing as it's global at the class level, I
don't think that argument flies.

Now, as I said in my prior post, I am actually in favor of this change. I
think it can make patching existing architectures and legacy code much
easier. But I wouldn't write new code with it. And I wouldn't say that it's
a good compliment to OOP. It can help in certain situations, but it also
can cause a lot of pain (due to the global nature, and the fact that it is
really just spooky-action-at-a-distance).
http://en.wikipedia.org/wiki/Action_at_a_distance_(computer_programming)

Anthony

Reply via email to