Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:62456 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 40804 invoked from network); 24 Aug 2012 19:14:30 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 24 Aug 2012 19:14:30 -0000 Authentication-Results: pb1.pair.com smtp.mail=ircmaxell@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=ircmaxell@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.217.170 as permitted sender) X-PHP-List-Original-Sender: ircmaxell@gmail.com X-Host-Fingerprint: 209.85.217.170 mail-lb0-f170.google.com Received: from [209.85.217.170] ([209.85.217.170:56435] helo=mail-lb0-f170.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 39/F2-24287-492D7305 for ; Fri, 24 Aug 2012 15:14:29 -0400 Received: by lbbgp3 with SMTP id gp3so1365297lbb.29 for ; Fri, 24 Aug 2012 12:14:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=QAzdjlUQpm9HXVzXw/7+nKjlzbb6ZbP4RtcQaQ0rkhc=; b=E9QISckKuZ6b0NISgFYN/C5Wo0aQn+0/Y+pBTg6lsEeO8DP/9OrXtS8u1kgtFe/xHQ nS148HGG3irmZkT18BEmjoS8DxTf7ywtWay56gQ1fwuMuEARHxX5VkAntZbOb/tY2LOW J4mc+FubLH2eFdl7ne+OKtzBY5RxkVZT8COpfAJ7kZdDznSRmu5QSW66F7M+gIohp8Di 0z5ewyB/mm9+jQf2BUl5RTu3dp34pHvLUNNxw7MZ4/Wgvghl6i/IZkLtQGUtbU2EqPsv F0PU8ZFe0Q5N0WSu2pSISkgN4kne50An0tGQMjxa+xCQKq7pmR2XYkNfJ4rijRazs8dc 7qYw== MIME-Version: 1.0 Received: by 10.152.146.169 with SMTP id td9mr6791258lab.42.1345835664389; Fri, 24 Aug 2012 12:14:24 -0700 (PDT) Received: by 10.114.57.207 with HTTP; Fri, 24 Aug 2012 12:14:24 -0700 (PDT) In-Reply-To: References: <50369892.6080106@googlemail.com> Date: Fri, 24 Aug 2012 15:14:24 -0400 Message-ID: To: Peter Nguyen Cc: dukeofgaming , Sebastian Krebs , internals@lists.php.net Content-Type: multipart/alternative; boundary=e89a8f234589b3b5e704c807c85d Subject: Re: [PHP-DEV] Aspect Oriented Programming in PHP From: ircmaxell@gmail.com (Anthony Ferrara) --e89a8f234589b3b5e704c807c85d Content-Type: text/plain; charset=ISO-8859-1 Peter, On Fri, Aug 24, 2012 at 2:36 PM, Peter Nguyen 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 --e89a8f234589b3b5e704c807c85d--