Decorator pattern

ActionScript no soporta herencia múltiple, si alguna vez te has visto en una situación en la que te hubiera gustado que así fuera es muy posible que hayas llegado a algún recurso donde se explica lo que es el patrón de diseño Decorator o, porque no, que lo hayas implementado sin saber que tenía un nombre.

Un Decorator es una clase con la que se puede ejecutar funcionalidad de varias clases a la vez. Si se utiliza bien es equivalente a disponer de herencia múltiple pero sin los dolores de cabeza que ésta conlleva.
La idea básicamente pasa por componer una clase con funcionalidad de otra mediante la instanciación de ésta y la implementación de todos sus métodos.

Un ejemplo básico ( dedicado a mi suegra que escribe con las dos manos! ) para ilustrar una implementación:

Actionscript:
  1. class Diestro{
  2.     public function escribeConLaDerecha(){}
  3. }
  4. class Zurdo{
  5.     public function escribeConLaIzquierda(){}
  6. }
  7. // ésta es la implementación de Decorator
  8. class Ambidiestro extends Diestro{
  9.     private var zurdo:Zurdo = new Zurdo();
  10.     public function escribeConLaIzquierda(){
  11.         zurdo.escribeConLaIzquierda();
  12.     }
  13. }

Aquí podemos claramente que la única forma de que un Ambidiestro pueda escribir con las dos manos es a través de la composición. Esto está bien si queremos adquirir la funcionalidad de un Diestro y de un Zurdo sin más, pero hay un pequeño fallo... podemos tratar a un Ambidiestro como un Diestro porque extiende de Diestro, pero en cambio si queremos tratar a un Ambidiestro como un Zurdo no vamos a poder porque no extiende de Zurdo.
Dicho de otra forma...

podemos hacer:

Actionscript:
  1. var ambidiestroDeDiestro:Diestro = new AmbiDiestro();

pero NO podemos hacer:

Actionscript:
  1. var ambidiestroDeZurdo:Zurdo = new AmbiDiestro();

Llegados a este punto la solución es utilizar una interfaz.
El ejemplo completo sería este:

Actionscript:
  1. interface IZurdo{
  2.     public function escribeConLaIzquierda(){}
  3. }
  4. interface IDiestro{
  5.     public function escribeConLaDerecha(){}
  6. }
  7. class Diestro implements IDiestro{
  8.     public function escribeConLaDerecha(){}
  9. }
  10. class Zurdo implements IZurdo{
  11.     public function escribeConLaIzquierda(){}
  12. }
  13. // ésta es la implementación de Decorator
  14. class AmbiDiestro extends Diestro implements IZurdo{
  15.     private var zurdo:Zurdo = new Zurdo();
  16.     public function escribeConLaIzquierda(){
  17.         zurdo.escribeConLaIzquierda();
  18.     }
  19. }
  20.  
  21. // ahora si, un ambidiestro es un IDiestro y un IZurdo:
  22. var ambidiestroDeDiestro:IDiestro = new AmbiDiestro()
  23. ambidiestroDeDiestro.escribeConLaDerecha();
  24.  
  25. var ambidiestroDeZurdo:IZurdo = new AmbiDiestro()
  26. ambidiestroDeZurdo.escribeConLaIzquierda();

Ahora si podemos tratar a un Ambidiestro como un Zurdo y como un Diestro a través de IZurdo e IDiestro respectivamente.

Un ejemplo en la vida real y muy común de una implementación del patrón Decorator es cuando queremos que una clase sea un EventDispatcher cuando ya hereda de otra clase que no lo es. La clase mx.rpc.AbstractService de Flex es un ejemplo de ello. Esta clase extiende de flash.utils.Proxy, que no es un EventDispatcher y mediante composición de una instancia de EventDispatcher e implementando la interfaz flash.events.IEventDispatcher pasa a ser un EventDispatcher en toda regla.

Comments

3 Responses to “Decorator pattern”

  1. Jack on August 9th, 2008 06:17

    vaya que mejor explicado y mas facil de comprender no se hubiera podido lograr.. sigo atento a tus post y a tus enseñanzas.. Gracias por la implementacion de herencia multiple..

  2. Adapter pattern : Joan Garnet :: RIA Architecture on August 12th, 2008 21:23

    [...] en principio no debería poder utilizarse. Implementacionalmente el patrón es muy parecido al Decorator, pero conceptualmente cada uno está muy diferenciado del otro, y como que los patrones tienen [...]

  3. Carbonell on January 21st, 2010 10:03

    Looks like I was a bit late on this one but it's really a good post. I'm thinking about a reply on my site . . .

Leave a Reply