# Decorator classes

- Thread: https://externals.io/message/97480
- Original archive: https://news-web.php.net/php.internals/97480
- Started by Mathieu Rochette on 2016-12-29T13:12:33+00:00
- Messages: 6
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #97480 — Mathieu Rochette — 2016-12-29T13:12:33+00:00

URL: https://externals.io/message/97480#97480

Hello internals,

I find that using the decorator pattern is very verbose and maybe 
something could be done about that,
an article[1] I saw proposed a "decorates" keyword to solves this, here 
is how it might look like in PHP:

interface Foo {
   public bar();
   public taz();
}

class EchoFooBar decorates Foo {
   public function bar() {
     $this->logger->debug("foo bar");
     return $this->decorated->bar();
   }
}

class LoggedFooTaz decorates Foo {
   private $logger;

   public function __construct(Foo $decorated, Logger $logger) {
     $this->logger = $logger;
     $this->decorated = $decorated;
   }

   public function taz() {
     $this->logger->debug("foo taz");
     return $this->decorated->taz();
   }
}

* the constructor is optional and default to take the first argument and 
put it in $decorated
* if the constructor is provided PHP check that $decorated is set and 
implements the decorated interface or class
* all public methods not overridden are automatically proxied to the 
decorated object

There is at least a few different ways to go about this, the previous 
example was just to give you a preview of what it could be. If there is 
interest I'd like to write an RFC for this :)

What do you think about this ?


thank you


[1] https://dzone.com/articles/is-inheritance-dead

---

## #97481 — Marco Pivetta — 2016-12-29T13:18:05+00:00

URL: https://externals.io/message/97480#97481 · In reply to: #97480

On Thu, Dec 29, 2016 at 2:12 PM, Mathieu Rochette <mathieu@rochette.cc>
wrote:

> Hello internals,
>
> I find that using the decorator pattern is very verbose and maybe
> something could be done about that,
> an article[1] I saw proposed a "decorates" keyword to solves this, here is
> how it might look like in PHP:
>
> interface Foo {
>   public bar();
>   public taz();
> }
>
> class EchoFooBar decorates Foo {
>   public function bar() {
>     $this->logger->debug("foo bar");
>     return $this->decorated->bar();
>   }
> }
>
> class LoggedFooTaz decorates Foo {
>   private $logger;
>
>   public function __construct(Foo $decorated, Logger $logger) {
>     $this->logger = $logger;
>     $this->decorated = $decorated;
>   }
>
>   public function taz() {
>     $this->logger->debug("foo taz");
>     return $this->decorated->taz();
>   }
> }
>
> * the constructor is optional and default to take the first argument and
> put it in $decorated
> * if the constructor is provided PHP check that $decorated is set and
> implements the decorated interface or class
> * all public methods not overridden are automatically proxied to the
> decorated object
>
> There is at least a few different ways to go about this, the previous
> example was just to give you a preview of what it could be. If there is
> interest I'd like to write an RFC for this :)
>
> What do you think about this ?
>
>
> thank you
>
>
> [1] https://dzone.com/articles/is-inheritance-dead
>
> --
> 
> 
>
>
Just my 2 cents:

Too much magic syntactic sugar, whereas you are just saving very little
time while implementing a few method stubs that take..

Yet, in order to achieve that, you added a huge amount of complexity for
all the tooling that  relies on the AST, including PHP itself.
.
Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/

---

## #97482 — Alexander Lisachenko — 2016-12-29T13:44:19+00:00

URL: https://externals.io/message/97480#97482 · In reply to: #97480

2016-12-29 16:12 GMT+03:00 Mathieu Rochette <mathieu@rochette.cc>:

> I find that using the decorator pattern is very verbose and maybe
> something could be done about that,
> an article[1] I saw proposed a "decorates" keyword to solves this, here is
> how it might look like in PHP:
>


> * the constructor is optional and default to take the first argument and
> put it in $decorated
> * if the constructor is provided PHP check that $decorated is set and
> implements the decorated interface or class
> * all public methods not overridden are automatically proxied to the
> decorated object
>
> There is at least a few different ways to go about this, the previous
> example was just to give you a preview of what it could be. If there is
> interest I'd like to write an RFC for this :)
>
> What do you think about this ?
>

Hi! I think that language doesn't need any additional keywords for that.
What you describe is pure class inheritance and it's already available in
the language.

To be honest I use class inheritance in Go! AOP to define decorators
because of some nice features:

   1. No overhead for calling non-decorated method (we can wrap only
   required methods)
   2. Only one single instance of class, whereas traditional proxy and
   decorator pattern will use two instances (one for the original instance
   itself and one more instance for proxy/decorator)

What your want can be implemented with the help of one single aspect,
applied to your codebase. Then framework will automatically create
decorators for every required class in your system. For logging decorator
example see my blogpost here:
http://go.aopphp.com/blog/2013/07/21/implementing-logging-aspect-with-doctrine-annotations/

---

## #97483 — Mathieu Rochette — 2016-12-29T14:18:53+00:00

URL: https://externals.io/message/97480#97483 · In reply to: #97482

>
> 2016-12-29 16:12 GMT+03:00 Mathieu Rochette <mathieu@rochette.cc 
> <mailto:mathieu@rochette.cc>>:
>
>     I find that using the decorator pattern is very verbose and maybe
>     something could be done about that,
>     an article[1] I saw proposed a "decorates" keyword to solves this,
>     here is how it might look like in PHP:
>
>
>     * the constructor is optional and default to take the first
>     argument and put it in $decorated
>     * if the constructor is provided PHP check that $decorated is set
>     and implements the decorated interface or class
>     * all public methods not overridden are automatically proxied to
>     the decorated object
>
>     There is at least a few different ways to go about this, the
>     previous example was just to give you a preview of what it could
>     be. If there is interest I'd like to write an RFC for this :)
>
>     What do you think about this ?
>
>
> Hi! I think that language doesn't need any additional keywords for 
> that. What you describe is pure class inheritance and it's already 
> available in the language.
It is not class inheritance, as you can see in my example, the decorator 
is on an interface. one point of the decorator pattern is that you don't 
need to know
which class (or subclass) you are decorating. any object implementing 
the interface (or extending the class if it's a class you are 
decorating) can be decorated.

>
> To be honest I use class inheritance in Go! AOP to define decorators 
> because of some nice features:
>
>  1. No overhead for calling non-decorated method (we can wrap only
>     required methods)
>
I think PHP could be smart enough to do that too for non-decorated 
methods with the decorates keyword
>
>  1. Only one single instance of class, whereas traditional proxy and
>     decorator pattern will use two instances (one for the original
>     instance itself and one more instance for proxy/decorator)
>
I'm not sure decorator is appropriate here, in the article you are not 
decorating[1] your class; you are outsourcing the behavior but it's not 
the same
>
> What your want can be implemented with the help of one single aspect, 
> applied to your codebase. Then framework will automatically create 
> decorators for every required class in your system. For logging 
> decorator example see my blogpost here: 
> http://go.aopphp.com/blog/2013/07/21/implementing-logging-aspect-with-doctrine-annotations/
>

[1] https://en.wikipedia.org/wiki/Decorator_pattern

---

## #97485 — Mathieu Rochette — 2016-12-29T14:27:30+00:00

URL: https://externals.io/message/97480#97485 · In reply to: #97481

>
> On Thu, Dec 29, 2016 at 2:12 PM, Mathieu Rochette <mathieu@rochette.cc 
> <mailto:mathieu@rochette.cc>> wrote:
>
>     Hello internals,
>
>     I find that using the decorator pattern is very verbose and maybe
>     something could be done about that,
>     an article[1] I saw proposed a "decorates" keyword to solves this,
>     here is how it might look like in PHP:
>
>     interface Foo {
>       public bar();
>       public taz();
>     }
>
>     class EchoFooBar decorates Foo {
>       public function bar() {
>         $this->logger->debug("foo bar");
>         return $this->decorated->bar();
>       }
>     }
>
>     class LoggedFooTaz decorates Foo {
>       private $logger;
>
>       public function __construct(Foo $decorated, Logger $logger) {
>         $this->logger = $logger;
>         $this->decorated = $decorated;
>       }
>
>       public function taz() {
>         $this->logger->debug("foo taz");
>         return $this->decorated->taz();
>       }
>     }
>
>     * the constructor is optional and default to take the first
>     argument and put it in $decorated
>     * if the constructor is provided PHP check that $decorated is set
>     and implements the decorated interface or class
>     * all public methods not overridden are automatically proxied to
>     the decorated object
>
>     There is at least a few different ways to go about this, the
>     previous example was just to give you a preview of what it could
>     be. If there is interest I'd like to write an RFC for this :)
>
>     What do you think about this ?
>
>
>     thank you
>
>
>     [1] https://dzone.com/articles/is-inheritance-dead
>     <https://dzone.com/articles/is-inheritance-dead>
>
>     -- 
>     
>     
>
>
> Just my 2 cents:
>
> Too much magic syntactic sugar, whereas you are just saving very 
> little time while implementing a few method stubs that take..
yeah it's mostly syntactic sugar, I think it would encourage developer 
to use this pattern instead of inheritance when appropriate.
I also think that most of the time using the decorator pattern helps 
following the single responsibility principle

also, this would add one more benefit : methods that are not override 
could probably be optimized by the PHP engine (avoid one userland proxy 
call)
>
> Yet, in order to achieve that, you added a huge amount of complexity 
> for all the tooling that  relies on the AST, including PHP itself.
> .
> Marco Pivetta
>
> http://twitter.com/Ocramius
>
> http://ocramius.github.com/

---

## #97486 — Marco Pivetta — 2016-12-29T14:43:49+00:00

URL: https://externals.io/message/97480#97486 · In reply to: #97485

On Thu, Dec 29, 2016 at 3:27 PM, Mathieu Rochette <mathieu@rochette.cc>
wrote:

> yeah it's mostly syntactic sugar, I think it would encourage developer to
> use this pattern instead of inheritance when appropriate.
> I also think that most of the time using the decorator pattern helps
> following the single responsibility principle
>

Meh, just `final` as much as possible, combined with interfaces :-)


> also, this would add one more benefit : methods that are not override
> could probably be optimized by the PHP engine (avoid one userland proxy
> call)
>

That's probably something that opcache could do anyway.

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/
