Frage

Ich fange gerade an, Designmuster zu lernen, und ich habe zwei Fragen zum Dekorateur ...

Ich habe mich gefragt, warum das Dekorationsmuster darauf hindeutet, dass der Dekorateur alle öffentlichen Methoden der Komponente implementiert, deren Dekoration er dekoriert?

Kann die Dekorateurklasse nicht nur verwendet werden, um das zusätzliche Verhalten zu liefern, und dann die Betonkomponente (die in sie übergeben wird) einfach verwendet werden, um alles andere zu nennen?

Und zweitens, was ist, wenn die konkrete Komponente, die Sie dekorieren möchten, keine Basisklasse hat, aus der der abstrakte Dekorateur auch ableiten kann?

Danke im Voraus!

War es hilfreich?

Lösung

Ich denke, Sie haben Dekorateur missverstanden. Sie denken an einen einfachen Fall, in dem eine konkrete Klasse mit zusätzlicher Funktionalität erweitert wird. In diesem Fall kann Ja, in den meisten OO -Sprachen, die die abgeleitete Klasse einfach ermöglichen kann, dass ihre Superklasse alle nicht implementierten Methoden behandeln.

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
  }

}

Eine Dekorateurklasse nicht erweitern Die Grundklasse seiner "dekorierten" Klasse. Es ist ein anderer Typ, der ein Mitgliedsobjekt der dekorierten Klasse hat. Somit muss es dieselbe Schnittstelle implementieren, wenn sie nur die jeweilige Methode des dekorierten Objekts aufrufen.

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
  }

}

Es könnte sich lohnen, eine zu definieren Schnittstelle (Wenn Ihre Sprache so etwas unterstützt) sowohl für die dekorierte Klasse als auch für die Dekorationsklasse. Auf diese Weise können Sie zur Kompilierung der Kompilierung überprüft, ob der Dekorateur dieselbe Schnittstelle implementiert.

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

class Base implements IBase {
  . . .
}

class Decorator implements IBase {
  . . .
}

Re: @yossi Dahans Kommentar: Ich sehe die Mehrdeutigkeit im Wikipedia -Artikel, aber wenn Sie sorgfältig lesen aufstellen Im Dekorateurobjekt und die Komponente wird als Argument an den Dekorateurkonstruktor übergeben. Dies unterscheidet sich von der Vererbung.

Obwohl der Wikipedia -Artikel sagt, dass der Dekorateur die Komponente erbt, sollten Sie dies als Implementierung einer Schnittstelle betrachten, wie ich im obigen PHP -Beispiel gezeigt habe. Der Dekorateur muss immer noch für das Komponentenobjekt stäben, was er nicht tun würde, wenn es geerbt wäre. Dadurch kann der Dekorateur ein Objekt von dekorieren irgendein Klasse, die diese Schnittstelle implementiert.

Hier sind einige Auszüge aus "Designmuster: Elemente wiederverwendbarer objektorientierter Software" von Gamma, Helm, Johnson und Vlissides:

Dekorateur

Absicht

Fügen Sie einem Objekt dynamisch zusätzliche Verantwortung bei. Dekorateure bieten eine flexible Alternative zur Unterklasse für die Erweiterung der Funktionalität.

Motivation

... Ein Dekorateur entspricht der Schnittstelle der Komponente, die er dekoriert, damit seine Anwesenheit für die Kunden der Komponente transparent ist.

Teilnehmer

  • Der Dekorateur behält einen Verweis auf ein Komponentenobjekt und definiert eine Schnittstelle, die der Schnittstelle der Komponenten entspricht.

Andere Tipps

Ich habe mich gefragt, warum das Dekorationsmuster darauf hindeutet, dass der Dekorateur alle öffentlichen Methoden der Komponente implementiert, deren Dekoration er dekoriert?

Ein Dekorateur sollte ein Ersatz für die Komponente sein, die er dekoriert, mit zusätzlicher Funktionalität ("Dekoration"). Dies kann nur passieren, wenn es die Schnittstelle der Komponente vollständig implementiert.

Kann die Dekorateurklasse nicht nur verwendet werden, um das zusätzliche Verhalten zu liefern, und dann die Betonkomponente (die in sie übergeben wird) einfach verwendet werden, um alles andere zu nennen?

Das macht Annahmen darüber, wie der Dekorateur implementiert wird. Sie können nicht sicher sein, dass die gesamte öffentliche Schnittstelle der Komponente, die sie dekoriert, direkt durchlaufen wird. Es ist möglich, dass der Dekorator bestimmte Methoden in seiner Implementierung außer Kraft setzt.

Und zweitens, was ist, wenn die konkrete Komponente, die Sie dekorieren möchten, keine Basisklasse hat, aus der der abstrakte Dekorateur auch ableiten kann?

Dekorateure erben im Allgemeinen die Klasse der Komponente, die sie dekorieren, nicht die Basis der Komponente.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top