Decorator GrundlagenÜbersicht über das Decorator PatternAm Beginn behandeln wir einige Hintergründe des » Decorator Design Patterns. Eine verbreitetere Technik ist die Definition eines gemeinsamen Interfaces welche sowohl das originale Objekt als auch alle von Ihm abhängigen implementieren; der Decorator akzeptiert dann das originale Objekt als abhängiges, und wird entweder darauf verweisen oder seine Methoden überschreiben. Schreiben wir etwas Code damit es leichter verständlich wird:
Wir haben ein Objekt vom Typ StandardWindow erstellt, es dem Contructor von LockedWindow übergeben, und die eigene Fenster Instanz hat jetzt ein anderes Verhalten. Das Schöne daran ist, das man keine Art von "Locking" Funktionalität in der standardmäßigen Fenster Klasse implementieren muss -- der Decorator passt für einen darauf auf. In der Zwischenzeit kann das gesperrte Fenster herum übergeben wie wenn ein nur ein anderes Fenster wäre. Ein spezieller Platz an dem das Decorator Pattern nützlich ist, ist die Erstellung von textuellen Repräsentationen von Objekten. Als Beispiel könnte man ein "Person" Objekt haben welches, aus sich selbst heraus, keine textuelle Repräsentation hat. Durch Verwendung des Decorator Patterns arbeitet es als wäre es eine Peron, bietet aber auch die Möglichkeit diese Person textuell darzustellen. In diesem speziellen Beispiel, werden wir ein sogenanntes » Duck Typing verwenden statt einem expliziten Interface. Das erlaubt unserer Implementation etwas flexibler zu sein, wärend es dem Decorator Pattern trotzdem noch erlaubt so exakt zu arbeiten als wäre es ein Personen Objekt.
In diesem Beispiel übergeben wir unsere Instanz von Person an den Constructor von TextPerson. Durch Verwendung von Methoden Überladung sind wir in der Lage weiterzumachen und alle Methoden von Person auf Ihr aufzurufen -- um den Vornamen, den Nachnamen, oder den Titel zu setzen -- aber man erhält jetzt auch eine String Repräsentation über die __toString() Methode. Das letztere Beispiel kommt der Arbeitsweise der Decorators von Zend_Form schon nahe. Der eigentliche Unterschied besteht darin, das statt den Decorator in einem Element einzubetten, das Element ein oder mehrere Decorators angehängt haben kann welche es dann in sich selbst injiziert und weiterhin Eigenschaften um eine Repräsentation des Elements -- oder einem Subset von sich -- zu erstellen. Den ersten Decorator erstellenZend_Form Decorators implementieren alle ein gemeinsames Interface Zend_Form_Decorator_Interface. Dieses Interface bietet die Fähigkeit decorator-spezifische Optionen zu setzen, das Element zu registrieren und zu empfangen, und darzustellen. Der Basis Decorator, Zend_Form_Decorator_Abstract, bietet die jede Funktionalität welche man irgendwann verwenden wird, mit Ausnahme der Logik für die Darstellung. Nehmen wir eine Situation an in der wir einfach ein Element als Standard Formular Texteinfabe mit einer Überschrift darstellen wollen. Wir denken jetzt nicht an Fehlerbehandlung oder ob das Element mit anderen Tags umhüllt werden soll oder nicht -- nur die Grundlagen. Solch ein Decorator könnte wie folgt aussehen:
Erstellen wir ein Element welches diesen Decorator verwendet: Die Darstellung dieses Elements führt zum folgenden Markup:
Man könnte diese Klasse auch irgendwo in die eigene Bibliothek geben, das Element über den Pfad informieren, und auf den Decorator genauso einfach als "SimpleInput" verweisen: Das gibt den Vorteil das er auch in anderen Projekten wiederverwendet werden kann, und öffnet die Türen damit später alternative Implementationen dieses Decorators angeboten werden können. Im nächsten Abschnitt schauen wir uns an wie Decorators kombiniert werden können um kombinierte Ausgaben zu erstellen.
|