fbpx
Wikipedia

Decorator (patrón de diseño)

El patrón Decorator responde a la necesidad de añadir dinámicamente funcionalidad a un Objeto. Esto nos permite no tener que crear sucesivas clases que hereden de la primera incorporando la nueva funcionalidad, sino otras que la implementan y se asocian a la primera.

Motivación

Un ejemplo para poder ver la aplicabilidad del patrón decorador podría ser el siguiente:

  • Disponemos de una herramienta para crear interfaces gráficas, que permite añadir funcionalidades como bordes o barras de desplazamiento a cualquier componente de la interfaz.
  • Una posible solución sería utilizar la herencia para extender las responsabilidades de la clase. Si optamos por esta solución, estaríamos haciendo un diseño inflexible (estático), ya que el cliente no puede controlar cuándo y cómo decorar el componente con esa propiedad.
  • La solución está en encapsular dentro de otro objeto, llamado Decorador, las nuevas responsabilidades. El decorador redirige las peticiones al componente y, además, puede realizar acciones adicionales antes y después de la redirección. De este modo, se pueden añadir decoradores con cualidades añadidas recursivamente.

 

  • En este diagrama de clases, podemos ver que la interfaz decorador implementa la interfaz del componente, redirigiendo todos los métodos al componente visual que encapsula.
  • Las subclases decoradoras refinan los métodos del componente, añadiendo responsabilidades.
  • También se puede ver que el cliente no necesita hacer distinción entre los componentes visuales decorados y los sin decorar.

 

Aplicabilidad

  • Añadir responsabilidades a objetos individuales de forma dinámica y transparente
  • Responsabilidades de un objeto pueden ser retiradas
  • Cuando la extensión mediante la herencia no es viable
  • Hay una necesidad de extender la funcionalidad de una clase, pero no hay razones para extenderlo a través de la herencia.
  • Existe la necesidad de extender dinámicamente la funcionalidad de un objeto y quizás quitar la funcionalidad extendida.

Estructura

 

Participantes

  • Componente

Define la interfaz para los objetos que pueden tener responsabilidades añadidas.

  • Componente Concreto

Define un objeto al cual se le pueden agregar responsabilidades adicionales.

  • Decorador

Mantiene una referencia al componente asociado. Implementa la interfaz de la superclase Componente delegando en el componente asociado.

  • Decorador Concreto

Añade responsabilidades al componente.

Colaboraciones

  • El decorador redirige las peticiones al componente asociado.
  • Opcionalmente puede realizar tareas adicionales antes y después de redirigir la petición.

Consecuencias

  • Más flexible que la herencia. Al utilizar este patrón, se pueden añadir y eliminar responsabilidades en tiempo de ejecución. Además, evita la utilización de la herencia con muchas clases y también, en algunos casos, la herencia múltiple.
  • Evita la aparición de clases con muchas responsabilidades en las clases superiores de la jerarquía. Este patrón nos permite ir incorporando de manera incremental responsabilidades.
  • Genera gran cantidad de objetos pequeños. El uso de decoradores da como resultado sistemas formados por muchos objetos pequeños y parecidos.
  • Puede haber problemas con la identidad de los objetos. Un decorador se comporta como un envoltorio transparente. Pero desde el punto de vista de la identidad de objetos, estos no son idénticos, por lo tanto no deberíamos apoyarnos en la identidad cuando estamos usando decoradores.

Implementación

El patrón Decorator soluciona este problema de una manera mucho más sencilla y extensible.

Se crea a partir de Ventana la subclase abstracta VentanaDecorator y, heredando de ella, BordeDecorator y BotonDeAyudaDecorator. VentanaDecorator encapsula el comportamiento de Ventana y utiliza composición recursiva para que sea posible añadir tantas "capas" de Decorators como se desee. Podemos crear tantos Decorators como queramos heredando de VentanaDecorator.


Ejemplo C++

//[Clase Component] ver diagrama de clases class IVentanaAbstracta { public: virtual void Dibujar() = 0; }; //[Clase ConcreteComponent] ver diagrama de clases, Clase que se desea decorar class Ventana : public IVentanaAbstracta { public: void Dibujar() {  std::cout << " Ventana "; } }; //[Clase Decorator] ver diagrama de clases class VentanaDecorator : public IVentanaAbstracta { public: VentanaDecorator(IVentanaAbstracta* ventanaAbstracta) {  _VentanaAbstracta = ventanaAbstracta; } virtual void Dibujar() = 0; protected: IVentanaAbstracta* _VentanaAbstracta; }; //[Clase ConcreteDecorator] ver diagrama de clases class BordeDecorator : public VentanaDecorator { public: BordeDecorator(IVentanaAbstracta* ventanaAbstracta) : VentanaDecorator(ventanaAbstracta) { } virtual void Dibujar() {  std::cout << "|";  _VentanaAbstracta->Dibujar();  std::cout << "|"; } }; //[Clase ConcreteDecorator] ver diagrama de clases class BotonDeAyudaDecorator : public VentanaDecorator { public: BotonDeAyudaDecorator(IVentanaAbstracta* ventanaAbstracta) : VentanaDecorator(ventanaAbstracta) { } virtual void Dibujar() {  _VentanaAbstracta->Dibujar();  std::cout << "[Boton de Ayuda]"; } }; int main() { BotonDeAyudaDecorator* ventanaConBotonDeAyuda = new BotonDeAyudaDecorator(new Ventana()); ventanaConBotonDeAyuda->Dibujar(); std::cout << std::endl; BordeDecorator* ventanaConBotonDeAyudaYBorde = new BordeDecorator(ventanaConBotonDeAyuda); ventanaConBotonDeAyudaYBorde->Dibujar(); std::cout << std::endl; BordeDecorator* ventanaConBorde = new BordeDecorator(new Ventana()); ventanaConBorde->Dibujar(); std::cout << std::endl; BordeDecorator* ventanaConDobleBorde = new BordeDecorator(ventanaConBorde); ventanaConDobleBorde->Dibujar(); std::cout << std::endl; delete ventanaConBotonDeAyuda; delete ventanaConBotonDeAyudaYBorde; delete ventanaConBorde; delete ventanaConDobleBorde; return 0; } 

Ejemplo C#

using System; using System.Collections.Generic; using System.Text; namespace Decorator { class Program { static void Main(string[] args) {  BotonDeAyudaDecorator ventanaConBotonDeAyuda = new BotonDeAyudaDecorator(new Ventana());  BordeDecorator ventanaConBotonDeAyudaYBorde = new BordeDecorator(ventanaConBotonDeAyuda);  ventanaConBotonDeAyudaYBorde.Dibujar();  Console.WriteLine();  BordeDecorator ventanaConBorde = new BordeDecorator(new Ventana());  ventanaConBorde.Dibujar();  Console.WriteLine();  BordeDecorator ventanaConDobleBorde = new BordeDecorator(ventanaConBorde);  ventanaConDobleBorde.Dibujar();  Console.WriteLine();   BordeDecorator ventanaConDobleBordeYBotonDeAyuda = new BordeDecorator(new BordeDecorator(ventanaConBotonDeAyuda));  ventanaConDobleBordeYBotonDeAyuda.Dibujar();  Console.WriteLine();  Console.Read(); } //[Clase Component] ver diagrama de clases public interface IVentanaAbstracta {  void Dibujar(); } //[Clase ConcreteComponent] ver diagrama de clases, Clase que se desea decorar public class Ventana : IVentanaAbstracta {  public void Dibujar() { Console.Write(" Ventana "); } } //[Clase Decorator] ver diagrama de clases public abstract class VentanaDecorator : IVentanaAbstracta {  public VentanaDecorator(IVentanaAbstracta ventanaAbstracta) { _VentanaAbstracta = ventanaAbstracta; }  protected IVentanaAbstracta _VentanaAbstracta;  public abstract void Dibujar(); } //[Clase ConcreteDecorator] ver diagrama de clases public class BordeDecorator : VentanaDecorator {  public BordeDecorator(IVentanaAbstracta ventanaAbstracta) : base(ventanaAbstracta) { }  public override void Dibujar() { Console.Write("|"); _VentanaAbstracta.Dibujar(); Console.Write("|"); }  } //[Clase ConcreteDecorator] ver diagrama de clases public class BotonDeAyudaDecorator : VentanaDecorator {  public BotonDeAyudaDecorator(IVentanaAbstracta ventanaAbstracta) : base(ventanaAbstracta) { }  public override void Dibujar() { _VentanaAbstracta.Dibujar(); Console.Write("[Boton de Ayuda]"); }  } } } 

Ejemplo Java

 public abstract class Componente{ abstract public void operacion(); } public class ComponenteConcreto extends Componente{ public void operacion(){ System.out.println("ComponenteConcreto.operacion()"); } } public abstract class Decorador extends Componente{ private Componente componente; public Decorador(Componente componente){ this.componente = componente; } public void operacion(){ componente.operacion(); } } public class DecoradorConcretoA extends Decorador{ private String propiedadAñadida; public DecoradorConcretoA(Componente componente){ super(componente); } public void operacion(){ super.operacion(); this.propiedadAñadida = "Nueva propiedad"; System.out.println("DecoradorConcretoA.operacion()"); } } public class DecoradorConcretoB extends Decorador{ public DecoradorConcretoB(Componente componente){ super(componente); } public void operacion(){ super.operacion(); comportamientoAñadido(); System.out.println("DecoradorConcretoB.operacion()"); } public void comportamientoAñadido(){ System.out.println("Comportamiento B añadido"); } } public class Cliente{ public static void main(String[] args){ ComponenteConcreto c = new ComponenteConcreto(); DecoradorConcretoA d1 = new DecoradorConcretoA(c); DecoradorConcretoB d2 = new DecoradorConcretoB(d1); d2.operacion();//output: "ComponenteConcreto.operacion()\n DecoradorConcretoA.operacion()\n Comportamiento B añadido\n DecoradorConcretoB.operacion()" } } 

Ejemplo Python

def establecer_costo_decorator(funcion): def envoltorio1(instancia, costo): funcion(instancia, costo) return envoltorio1 def obtener_costo_decorator(costo_adicional): def envoltorio1(funcion): def envoltorio2(instancia):  return funcion(instancia) + costo_adicional return envoltorio2 return envoltorio1 class Cafe(object): @establecer_costo_decorator def establecer_costo(self, costo): self.costo = costo @obtener_costo_decorator(0.5) @obtener_costo_decorator(0.7) @obtener_costo_decorator(0.2) def obtener_costo(self): return self.costo cafe = Cafe() cafe.establecer_costo(1.0) print (cafe.obtener_costo()) # 2.4 

Ejemplo de PHP

<?php interface iCoffee { public function getBaseCost(); } class Coffee implements iCoffee { protected $_baseCost = 0; public function getBaseCost() { return $this->_baseCost; } } class BlackCoffee extends Coffee { public function __construct() { $this->_baseCost = 5; } } abstract class CoffeeDecorator implements iCoffee { protected $_coffee; public function __construct(iCoffee $Coffee) { $this->_coffee = $Coffee; } } class WithCream extends CoffeeDecorator { public function getBaseCost() { return $this->_coffee->getBaseCost() + 1.5; } } class WithMilk extends CoffeeDecorator { public function getBaseCost() { return $this->_coffee->getBaseCost() + 4; } } class WithChocolate extends CoffeeDecorator { public function getBaseCost() { return $this->_coffee->getBaseCost() + 5; } } $coffee = new WithChocolate(new WithMilk(new WithCream(new BlackCoffee()))); echo 'El precio del cafe es: $' . $coffee->getBaseCost(); 

Ejemplo Delphi

Dividimos la implementación del decorador en un paquete llamado PaqueteDecorador.bpl (código a continuación)

unit PruebaDecorador; interface type IBebida = interface ['{C58DD7FD-EA4A-4419-A9DF-CED5D260810A}'] function getDescripcion : String; function precio : Real; end; TCafe = class(TInterfacedObject, IBebida) private FDescripcion : String; public constructor Create; function getDescripcion : String; function precio : Real; end; TLeche = class(TInterfacedObject, IBebida) private FDescripcion : String; public constructor Create; function getDescripcion : String; function precio : Real; end; TIngredientes = class(TInterfacedObject, IBebida) function getDescripcion : String; virtual; abstract; function precio : Real; virtual; abstract; end; TChocolate = class(TIngredientes) private FDescripcion : String; FBebida : IBebida; public constructor Create(TObject : IBebida); function getDescripcion : String; override; function precio : Real; override; end; TCereales = class(TIngredientes) private FDescripcion : String; FBebida : IBebida; public constructor Create(TObject : IBebida); function getDescripcion : String; override; function precio : Real; override; end; implementation uses Spring.Container, Spring.Services ; { TBebida } constructor TCafe.Create; begin FDescripcion := 'Cafe'; end; function TCafe.getDescripcion: String; begin Result := FDescripcion; end; function TCafe.precio: Real; begin Result := 1.00; end; { TChocolate } constructor TChocolate.Create(TObject: IBebida); begin FDescripcion := 'Chocolate (ing)'; FBebida := TObject; end; function TChocolate.getDescripcion: String; begin Result := FDescripcion + ' ' + FBebida.getDescripcion; end; function TChocolate.precio: Real; begin Result := 0.5 + FBebida.precio; end; { TCereales } constructor TCereales.Create(TObject: IBebida); begin FDescripcion := 'Cereales (ing)'; FBebida := TObject; end; function TCereales.getDescripcion: String; begin Result := FDescripcion + ' ' + FBebida.getDescripcion; end; function TCereales.precio: Real; begin Result := 0.2 + FBebida.precio; end; { TLeche } constructor TLeche.Create; begin FDescripcion := 'Leche'; end; function TLeche.getDescripcion: String; begin Result := FDescripcion; end; function TLeche.precio: Real; begin Result := 0.75; end; initialization GlobalContainer.RegisterType<TCafe>.Implements<IBebida>('Cafe'); GlobalContainer.RegisterType<TLeche>.Implements<IBebida>('Leche'); GlobalContainer.RegisterType<TChocolate>.Implements<IBebida>('Chocolate'); GlobalContainer.RegisterType<TCereales>.Implements<IBebida>('Cereales'); GlobalContainer.Build; end. 

y el código desde el que se invoca el paquete

program ConsolaDecorador; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, Spring.Services, // ServiceLocator PruebaDecorador; var cafe, leche: IBebida; begin try cafe := ServiceLocator.GetService<IBebida>('Cafe'); cafe := TChocolate.Create(cafe); cafe := TCereales.Create(cafe); writeln(cafe.precio); writeln(cafe.getDescripcion); leche := ServiceLocator.GetService<IBebida>('Leche'); leche := TChocolate.Create(leche); leche := TChocolate.Create(leche); writeln(leche.precio); writeln(leche.getDescripcion); except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; readln; end. 

Enlaces externos

  • Patrón Decorator: explicación y modelo UML
  • Patrón Decorator en PHP
  •   Datos: Q23839
  •   Multimedia: Decorator pattern

decorator, patrón, diseño, patrón, decorator, responde, necesidad, añadir, dinámicamente, funcionalidad, objeto, esto, permite, tener, crear, sucesivas, clases, hereden, primera, incorporando, nueva, funcionalidad, sino, otras, implementan, asocian, primera, Í. El patron Decorator responde a la necesidad de anadir dinamicamente funcionalidad a un Objeto Esto nos permite no tener que crear sucesivas clases que hereden de la primera incorporando la nueva funcionalidad sino otras que la implementan y se asocian a la primera Indice 1 Motivacion 2 Aplicabilidad 3 Estructura 4 Participantes 5 Colaboraciones 6 Consecuencias 7 Implementacion 7 1 Ejemplo C 7 2 Ejemplo C 7 3 Ejemplo Java 7 4 Ejemplo Python 7 5 Ejemplo de PHP 7 6 Ejemplo Delphi 8 Enlaces externosMotivacion EditarUn ejemplo para poder ver la aplicabilidad del patron decorador podria ser el siguiente Disponemos de una herramienta para crear interfaces graficas que permite anadir funcionalidades como bordes o barras de desplazamiento a cualquier componente de la interfaz Una posible solucion seria utilizar la herencia para extender las responsabilidades de la clase Si optamos por esta solucion estariamos haciendo un diseno inflexible estatico ya que el cliente no puede controlar cuando y como decorar el componente con esa propiedad La solucion esta en encapsular dentro de otro objeto llamado Decorador las nuevas responsabilidades El decorador redirige las peticiones al componente y ademas puede realizar acciones adicionales antes y despues de la redireccion De este modo se pueden anadir decoradores con cualidades anadidas recursivamente En este diagrama de clases podemos ver que la interfaz decorador implementa la interfaz del componente redirigiendo todos los metodos al componente visual que encapsula Las subclases decoradoras refinan los metodos del componente anadiendo responsabilidades Tambien se puede ver que el cliente no necesita hacer distincion entre los componentes visuales decorados y los sin decorar Aplicabilidad EditarAnadir responsabilidades a objetos individuales de forma dinamica y transparente Responsabilidades de un objeto pueden ser retiradas Cuando la extension mediante la herencia no es viable Hay una necesidad de extender la funcionalidad de una clase pero no hay razones para extenderlo a traves de la herencia Existe la necesidad de extender dinamicamente la funcionalidad de un objeto y quizas quitar la funcionalidad extendida Estructura Editar Participantes EditarComponenteDefine la interfaz para los objetos que pueden tener responsabilidades anadidas Componente ConcretoDefine un objeto al cual se le pueden agregar responsabilidades adicionales DecoradorMantiene una referencia al componente asociado Implementa la interfaz de la superclase Componente delegando en el componente asociado Decorador ConcretoAnade responsabilidades al componente Colaboraciones EditarEl decorador redirige las peticiones al componente asociado Opcionalmente puede realizar tareas adicionales antes y despues de redirigir la peticion Consecuencias EditarMas flexible que la herencia Al utilizar este patron se pueden anadir y eliminar responsabilidades en tiempo de ejecucion Ademas evita la utilizacion de la herencia con muchas clases y tambien en algunos casos la herencia multiple Evita la aparicion de clases con muchas responsabilidades en las clases superiores de la jerarquia Este patron nos permite ir incorporando de manera incremental responsabilidades Genera gran cantidad de objetos pequenos El uso de decoradores da como resultado sistemas formados por muchos objetos pequenos y parecidos Puede haber problemas con la identidad de los objetos Un decorador se comporta como un envoltorio transparente Pero desde el punto de vista de la identidad de objetos estos no son identicos por lo tanto no deberiamos apoyarnos en la identidad cuando estamos usando decoradores Implementacion EditarEl patron Decorator soluciona este problema de una manera mucho mas sencilla y extensible Se crea a partir de Ventana la subclase abstracta VentanaDecorator y heredando de ella BordeDecorator y BotonDeAyudaDecorator VentanaDecorator encapsula el comportamiento de Ventana y utiliza composicion recursiva para que sea posible anadir tantas capas de Decorators como se desee Podemos crear tantos Decorators como queramos heredando de VentanaDecorator Ejemplo C Editar Clase Component ver diagrama de clases class IVentanaAbstracta public virtual void Dibujar 0 Clase ConcreteComponent ver diagrama de clases Clase que se desea decorar class Ventana public IVentanaAbstracta public void Dibujar std cout lt lt Ventana Clase Decorator ver diagrama de clases class VentanaDecorator public IVentanaAbstracta public VentanaDecorator IVentanaAbstracta ventanaAbstracta VentanaAbstracta ventanaAbstracta virtual void Dibujar 0 protected IVentanaAbstracta VentanaAbstracta Clase ConcreteDecorator ver diagrama de clases class BordeDecorator public VentanaDecorator public BordeDecorator IVentanaAbstracta ventanaAbstracta VentanaDecorator ventanaAbstracta virtual void Dibujar std cout lt lt VentanaAbstracta gt Dibujar std cout lt lt Clase ConcreteDecorator ver diagrama de clases class BotonDeAyudaDecorator public VentanaDecorator public BotonDeAyudaDecorator IVentanaAbstracta ventanaAbstracta VentanaDecorator ventanaAbstracta virtual void Dibujar VentanaAbstracta gt Dibujar std cout lt lt Boton de Ayuda int main BotonDeAyudaDecorator ventanaConBotonDeAyuda new BotonDeAyudaDecorator new Ventana ventanaConBotonDeAyuda gt Dibujar std cout lt lt std endl BordeDecorator ventanaConBotonDeAyudaYBorde new BordeDecorator ventanaConBotonDeAyuda ventanaConBotonDeAyudaYBorde gt Dibujar std cout lt lt std endl BordeDecorator ventanaConBorde new BordeDecorator new Ventana ventanaConBorde gt Dibujar std cout lt lt std endl BordeDecorator ventanaConDobleBorde new BordeDecorator ventanaConBorde ventanaConDobleBorde gt Dibujar std cout lt lt std endl delete ventanaConBotonDeAyuda delete ventanaConBotonDeAyudaYBorde delete ventanaConBorde delete ventanaConDobleBorde return 0 Ejemplo C Editar using System using System Collections Generic using System Text namespace Decorator class Program static void Main string args BotonDeAyudaDecorator ventanaConBotonDeAyuda new BotonDeAyudaDecorator new Ventana BordeDecorator ventanaConBotonDeAyudaYBorde new BordeDecorator ventanaConBotonDeAyuda ventanaConBotonDeAyudaYBorde Dibujar Console WriteLine BordeDecorator ventanaConBorde new BordeDecorator new Ventana ventanaConBorde Dibujar Console WriteLine BordeDecorator ventanaConDobleBorde new BordeDecorator ventanaConBorde ventanaConDobleBorde Dibujar Console WriteLine BordeDecorator ventanaConDobleBordeYBotonDeAyuda new BordeDecorator new BordeDecorator ventanaConBotonDeAyuda ventanaConDobleBordeYBotonDeAyuda Dibujar Console WriteLine Console Read Clase Component ver diagrama de clases public interface IVentanaAbstracta void Dibujar Clase ConcreteComponent ver diagrama de clases Clase que se desea decorar public class Ventana IVentanaAbstracta public void Dibujar Console Write Ventana Clase Decorator ver diagrama de clases public abstract class VentanaDecorator IVentanaAbstracta public VentanaDecorator IVentanaAbstracta ventanaAbstracta VentanaAbstracta ventanaAbstracta protected IVentanaAbstracta VentanaAbstracta public abstract void Dibujar Clase ConcreteDecorator ver diagrama de clases public class BordeDecorator VentanaDecorator public BordeDecorator IVentanaAbstracta ventanaAbstracta base ventanaAbstracta public override void Dibujar Console Write VentanaAbstracta Dibujar Console Write Clase ConcreteDecorator ver diagrama de clases public class BotonDeAyudaDecorator VentanaDecorator public BotonDeAyudaDecorator IVentanaAbstracta ventanaAbstracta base ventanaAbstracta public override void Dibujar VentanaAbstracta Dibujar Console Write Boton de Ayuda Ejemplo Java Editar public abstract class Componente abstract public void operacion public class ComponenteConcreto extends Componente public void operacion System out println ComponenteConcreto operacion public abstract class Decorador extends Componente private Componente componente public Decorador Componente componente this componente componente public void operacion componente operacion public class DecoradorConcretoA extends Decorador private String propiedadAnadida public DecoradorConcretoA Componente componente super componente public void operacion super operacion this propiedadAnadida Nueva propiedad System out println DecoradorConcretoA operacion public class DecoradorConcretoB extends Decorador public DecoradorConcretoB Componente componente super componente public void operacion super operacion comportamientoAnadido System out println DecoradorConcretoB operacion public void comportamientoAnadido System out println Comportamiento B anadido public class Cliente public static void main String args ComponenteConcreto c new ComponenteConcreto DecoradorConcretoA d1 new DecoradorConcretoA c DecoradorConcretoB d2 new DecoradorConcretoB d1 d2 operacion output ComponenteConcreto operacion n DecoradorConcretoA operacion n Comportamiento B anadido n DecoradorConcretoB operacion Ejemplo Python Editar def establecer costo decorator funcion def envoltorio1 instancia costo funcion instancia costo return envoltorio1 def obtener costo decorator costo adicional def envoltorio1 funcion def envoltorio2 instancia return funcion instancia costo adicional return envoltorio2 return envoltorio1 class Cafe object establecer costo decorator def establecer costo self costo self costo costo obtener costo decorator 0 5 obtener costo decorator 0 7 obtener costo decorator 0 2 def obtener costo self return self costo cafe Cafe cafe establecer costo 1 0 print cafe obtener costo 2 4 Ejemplo de PHP Editar lt php interface iCoffee public function getBaseCost class Coffee implements iCoffee protected baseCost 0 public function getBaseCost return this gt baseCost class BlackCoffee extends Coffee public function construct this gt baseCost 5 abstract class CoffeeDecorator implements iCoffee protected coffee public function construct iCoffee Coffee this gt coffee Coffee class WithCream extends CoffeeDecorator public function getBaseCost return this gt coffee gt getBaseCost 1 5 class WithMilk extends CoffeeDecorator public function getBaseCost return this gt coffee gt getBaseCost 4 class WithChocolate extends CoffeeDecorator public function getBaseCost return this gt coffee gt getBaseCost 5 coffee new WithChocolate new WithMilk new WithCream new BlackCoffee echo El precio del cafe es coffee gt getBaseCost Ejemplo Delphi Editar Dividimos la implementacion del decorador en un paquete llamado PaqueteDecorador bpl codigo a continuacion unit PruebaDecorador interface type IBebida interface C58DD7FD EA4A 4419 A9DF CED5D260810A function getDescripcion String function precio Real end TCafe class TInterfacedObject IBebida private FDescripcion String public constructor Create function getDescripcion String function precio Real end TLeche class TInterfacedObject IBebida private FDescripcion String public constructor Create function getDescripcion String function precio Real end TIngredientes class TInterfacedObject IBebida function getDescripcion String virtual abstract function precio Real virtual abstract end TChocolate class TIngredientes private FDescripcion String FBebida IBebida public constructor Create TObject IBebida function getDescripcion String override function precio Real override end TCereales class TIngredientes private FDescripcion String FBebida IBebida public constructor Create TObject IBebida function getDescripcion String override function precio Real override end implementation uses Spring Container Spring Services TBebida constructor TCafe Create begin FDescripcion Cafe end function TCafe getDescripcion String begin Result FDescripcion end function TCafe precio Real begin Result 1 00 end TChocolate constructor TChocolate Create TObject IBebida begin FDescripcion Chocolate ing FBebida TObject end function TChocolate getDescripcion String begin Result FDescripcion FBebida getDescripcion end function TChocolate precio Real begin Result 0 5 FBebida precio end TCereales constructor TCereales Create TObject IBebida begin FDescripcion Cereales ing FBebida TObject end function TCereales getDescripcion String begin Result FDescripcion FBebida getDescripcion end function TCereales precio Real begin Result 0 2 FBebida precio end TLeche constructor TLeche Create begin FDescripcion Leche end function TLeche getDescripcion String begin Result FDescripcion end function TLeche precio Real begin Result 0 75 end initialization GlobalContainer RegisterType lt TCafe gt Implements lt IBebida gt Cafe GlobalContainer RegisterType lt TLeche gt Implements lt IBebida gt Leche GlobalContainer RegisterType lt TChocolate gt Implements lt IBebida gt Chocolate GlobalContainer RegisterType lt TCereales gt Implements lt IBebida gt Cereales GlobalContainer Build end y el codigo desde el que se invoca el paquete program ConsolaDecorador APPTYPE CONSOLE R res uses System SysUtils Spring Services ServiceLocator PruebaDecorador var cafe leche IBebida begin try cafe ServiceLocator GetService lt IBebida gt Cafe cafe TChocolate Create cafe cafe TCereales Create cafe writeln cafe precio writeln cafe getDescripcion leche ServiceLocator GetService lt IBebida gt Leche leche TChocolate Create leche leche TChocolate Create leche writeln leche precio writeln leche getDescripcion except on E Exception do Writeln E ClassName E Message end readln end Enlaces externos EditarPatron Decorator explicacion y modelo UML Patron Decorator en PHP Datos Q23839 Multimedia Decorator patternObtenido de https es wikipedia org w index php title Decorator patron de diseno amp oldid 126753534, wikipedia, wiki, leyendo, leer, libro, biblioteca,

español

, española, descargar, gratis, descargar gratis, mp3, video, mp4, 3gp, jpg, jpeg, gif, png, imagen, música, canción, película, libro, juego, juegos