Reply to comment

Decorator Pattern

Your rating: None Average: 3 (4 votes)

Das Decorator Pattern ermöglicht es ein Objekt zur Laufzeit zu erweitern oder dessen Methoden zu verändern. Dadurch erreicht man eine flexiblere Möglichkeit gegenüber statischer Vererbung, indem ein Objekt mit einem oder mehreren Dekorierern versehen wird.

Foo

Die mit Hilfe des Decorator Patterns zur erweiternde Klasse Foo. Diese implementiert ein beliebiges Interface.

interface RandomInterface {
 
  public function doSomething();
 
  public function doAnything();
 
  public function doNothing();
}
 
class Foo implements RandomInterface {
 
  public function doSomething() {
    // mach was oder return false
  }
 
  public function doAnything() {
    // mach was oder return false
  }
 
  public function doNothing() {
    // mach was oder return false
  }
}

FooDecorator

Der abstrakte Dekorierer der Klasse Foo bekommt im Konstruktor das zu dekorierende Objekt übergeben. Da auch dieser das RandomInterface implementiert, müssen alle Methoden der Schnittstelle bereitgestellt werden. Sie beinhalten jedoch lediglich die Funktionalität die Aufrufe an das zu dekorierende Objekt weiter zureichen.

abstract class FooDecorator implements RandomInterface {
 
  protected $_foo;
 
  public function __construct(RandomInterface $foo) {
    $this->_foo = $foo;
  }
 
  public function doSomething() {
    return $this->_foo->doSomething();
  }
 
  public function doAnything() {
    return $this->_foo->doAnything();
  }
 
  public function doNothing() {
    return $this->_foo->doNothing();
  }
}

FooExceptionDecorator

Dieser konkrete Dekorierer leitet vom FooDecorator ab und überschreibt dessen Methoden um die Erweiterung, bei der Rückgabe von false eine Exception zu werfen.

class FooExceptionDecorator extends FooDecorator {
 
  public function doSomething() {
    $something = $this->_foo->doSomething();
 
    if (false !== $something) {
      return $something;
    }
 
    throw new Exception('Die Methode '.__FUNCTION__.' beendete mit einem Fehler');
  }
 
  public function doAnything() {
    $anything = $this->_foo->doAnything();
 
    if (false !== $anything) {
      return $anything;
    }
 
    throw new Exception('Die Methode '.__FUNCTION__.' beendete mit einem Fehler');
  }
 
  public function doNothing() {
    $nothing = $this->_foo->doNothing();
 
    if (false !== $nothing) {
      return $nothing;
    }
 
    throw new Exception('Die Methode '.__FUNCTION__.' beendete mit einem Fehler');
  }
}

FooErrorDecorator

Im Gegensatz zum FooExceptionDecorator unterscheidet sich dieser konkrete Dekorierer darin, das er PHP Fehler statt Exceptions beim fehlschlagen der zu dekorierenden Methoden generiert.

class FooErrorDecorator extends FooDecorator {
 
  public function doSomething() {
    $something = $this->_foo->doSomething();
 
    if (false !== $something) {
      return $something;
    }
 
    trigger_error('Die Methode '.__FUNCTION__.' beendete mit einem Fehler', E_USER_ERROR);
  }
 
  public function doAnything() {
    $anything = $this->_foo->doAnything();
 
    if (false !== $anything) {
      return $anything;
    }
 
    trigger_error('Die Methode '.__FUNCTION__.' beendete mit einem Fehler', E_USER_ERROR);
  }
 
  public function doNothing() {
    $nothing = $this->_foo->doNothing();
 
    if (false !== $nothing) {
      return $nothing;
    }
 
    trigger_error('Die Methode '.__FUNCTION__.' beendete mit einem Fehler', E_USER_ERROR);
  }
}

Ich gebe zu, ein ziemlich einfaches Beispiel. Aber vielleicht dadurch um so verständlicher. Andere Möglichkeiten wären zum Beispiel ein Objekt darum zu erweitern, dessen Rückgaben von Beträgen in bestimmte Währungen oder Text-Ausgaben umzuwandeln oder Methoden um eine Logging-Funktionalität zu erweitern.

Reply

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <abbr>
  • Lines and paragraphs break automatically.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Image CAPTCHA
Enter the characters shown in the image.

Tags