Pregunta

Estoy empezando a aprender los patrones de diseño y tengo dos preguntas relacionadas con el decorador ...

Me preguntaba por qué el patrón decorador sugiere que el decorador de poner en práctica todos los métodos públicos del componente de la que decora?

No se puede simplemente la clase decorador ser utilizado para proporcionar los comportamientos adicionales, y entonces el componente de hormigón (que se pasa en ella) solo se utiliza para llamar a todo lo demás?

Y en segundo lugar, ¿y si el componente de hormigón que desea decorar no tiene una clase base que el decorador abstracto también puede derivar de?

Gracias de antemano!

¿Fue útil?

Solución

Creo que tienes haber entendido mal decorador. Usted está pensando en un caso simple de extender una clase concreta con la funcionalidad adicional. En este caso, sí en la mayoría de lenguajes orientados a la clase derivada puede simplemente permitir que su superclase para manejar cualquiera de los métodos no implementados.

class Base {

  function foo() {
    return "foo";
  }

  function bar() {
    return "bar";
  }

}

// Not what we think of as a Decorator,
// really just a subclass.
class Decorator extends Base {

  // foo() inherits behavior from parent Base class 

  function bar() {
    return parent::bar() . "!"; // add something
  }

}

Una clase decorador no extender la clase base de su clase "decorado". Es un tipo diferente, que tiene un objeto de miembro de la clase decorado. Por lo tanto, debe implementar la misma interfaz, aunque sólo sea para llamar al método respectivo del objeto decorado.

class Decorator { // extends nothing
  protected $base;

  function __construct(Base $base) {
    $this->base = $base;
  }

  function foo() {
    return $base->foo();
  }

  function bar() {
    return $base->foo() . "!"; // add something
  }

}

Podría ser útil para definir un Interfaz (si es compatible con su idioma tal cosa) tanto para la clase decorada y la clase decorador. De esta manera se puede comprobar en tiempo de compilación que el decorador implementa la misma interfaz.

interface IBase {
  function foo();
  function bar();
}

class Base implements IBase {
  . . .
}

class Decorator implements IBase {
  . . .
}

Re: comentario de @Yossi Dahan: Veo la ambigüedad en el artículo de Wikipedia, pero si usted lee cuidadosamente sí dice que el componente que se está decorada es un campo en el objeto decorador, y que el componente se pasa como argumento al constructor decorador. Esto es diferente de la herencia.

Aunque el artículo de wikipedia Qué dice la decoradora hereda del componente, se debe pensar en esto como la implementación de una interfaz, como he mostrado en el ejemplo anterior de PHP. El decorador todavía tiene que proxy para el objeto componente, lo que sería si no había heredado. Esto permite que el decorador para decorar un objeto de cualquier clase que implementa la interfaz.

Estos son algunos extractos de "Patrones de diseño: Elementos de software reutilizables orientada a objetos" de Gamma, Helm, Johnson y Vlissides:

  

decorador

     

Intención

     

Adjuntar responsabilidades adicionales a un objeto   dinamicamente. Decoradores proporcionan una   alternativa flexible a la subclasificación   para extender la funcionalidad.

     

Motivation

     

...   Un decorador se ajusta a la interfaz de   el componente que decora de manera que su   presencia es transparente para el   Los clientes de componentes.

     

Participantes

     
      
  • Decorador   mantiene una referencia a un objeto de componentes y define una interfaz   que se ajusta a la interfaz del componente.
  •   

Otros consejos

  

Me preguntaba por qué el patrón decorador sugiere que el decorador de poner en práctica todos los métodos públicos del componente de la que decora?

Un decorador debe ser una gota en el reemplazo para el componente que decora, con funcionalidad adicional (la "decoración"). Esto sólo puede ocurrir si se implementa por completo la interfaz del componente.

  

No se puede simplemente la clase decorador ser utilizado para proporcionar los comportamientos adicionales, y entonces el componente de hormigón (que se pasa en ella) solo se utiliza para llamar a todo lo demás?

Eso hace suposiciones sobre cómo se implementa el decorador. No se puede estar seguro de que toda la interfaz pública del componente que decora se está pasando a través directamente. Es posible que el decorador anula ciertos métodos en su aplicación.

  

Y en segundo lugar, ¿y si el componente de hormigón que desea decorar no tiene una clase base que el decorador abstracto también puede derivar de?

Decoradores generalmente heredan de clase del componente que están decorando, no la base del componente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top