Der Erklärbär: Aspect-Oriented Programming mit PHP – Teil 1 – Signal Slot

Wiedermal was Neues!? Wiedermal wird die (Web-)Programmierer-Welt auf den Kopf gestellt!? Objektorientiert ist gelber Schnee von Vorgestern, Design-Patterns verwendet heute schon deine Oma fürs Putzen … und jetzt kommt: TaTaaaa! AOP – Aspect Oriented Programming.

Der Erklärbär erklärt’s! (er versucht es zumindest)

AOP … was?! Noch nie gehört, oder doch?! … Ja auch die AOP gibst schon einige Jahre aber es dauert hald immer ein wenig bis die Sachen bei den Webentwicklern ankommen. Grundsätzlich geht es beim Aspect Orientierten Design darum die Schwächen der Objektorientierten Entwicklung auszubessern …

“Wie, was Schwächen der OOP?” … Ja klar, man kann zwar alle Klassen überschreiben oder erweitern aber was ist wenn man nur einen kleinen Teil einer Methode ändern will, dann muß man immer gleich die ganze Methode duplizieren und den kleinen Teil umschreiben. Aber das erzeugt viel unnötigen zusätzlichen Quelltext. Ausserdem kann es sein das diese Form der Erweiterung nicht Möglich ist und man an diversen Stellen dann die Methoden-Aufrufe umschreiben muß …. das will doch wirklich Keiner!

“Und AOP machts besser?” Ja, machts viel besser! Im Wikipedia wirds a bissl kompliziert erklärt: Verschiedene Aspekte (Concerns) die die ganze Applikation betreffen Bla Bla … … Konkret und einfach gesagt: Man kann hald net immer alles in ein Klassensystem pressen, gerade applikationsübergreifende Elemente wie Logging, Caching oder Parameter-Behandlung passen da überhaupt nicht rein und da springt dann die AOP ein.

Beispiel Logging:

In eine Methode ein Logging einzubauen ist ja relativ einfach:

public function doSomething() {
    $this->logger->log('start doSomething');
    // do something
    $this->logger->log('end doSomething'); 
}

Wunderbar! Jetzt hat man da den Logger drin und nach einer Woche will man aber auch an den selben Stellen etwas zusätzliches oder anderes machen lassen, Caching zum Beispiel, also bastelt mans dazu:

public function doSomething() {
    $this->logger->log('start doSomething');
    if ($this->inCache()) {
        // return from cache
    }
    // do something
    $this->logger->log('end doSomething'); 
}

Das wär ja auch noch ganz OK wenn man den Cache überall verwenden will, aber er soll hald nur unter gewissen Voraussetzungen verwendet werden, dann kann mans jetzt entweder der Methode als Parameter übergeben, oder als Klassenvariable dem Konstruktor, beides will man nicht weil man dann alle Aufrufe anpassen müsste (im schlimmsten Fall).

Rettung: Signals and Slots

Darum baut man sich einen “Signal Slot” hinein, früher hätte ich gesagt einen “Callback-Hook” oder im WordPress nennen sie es “Action”. Ein Signal markiert eine bestimmte Stelle im Quelltext aber ohne eine konkrete Aufgabe zu haben, in diesem Fall hätten wir ein Start-Signal und einen End-Signal, via Slots kann man den Signals eine Aufgabe zuordnen die aber nur in dem einen bestimmten Fall gilt und alle anderen Aufrufe nicht betrifft:

public function doSomething() {
    $this->signals()->emit('start');
    // do something
    $this->signals()->emit('end');
}
 
// attach slots somewhere else in the application
$class->signals()->connect('start', $log, 'info');
$class->signals()->connect('log', $log, 'info');

Nachteile der ganzen Sache: Wenn man die Signal-Slots ausgiebig verwendet, hat man hald viele “leere” emit-Calls im Quelltext die natürlich auch etwas Zeit für die Ausführung beanspruchen, also bissi schlechtere Performance. Nächster Nachteil, wenn man die Signals nicht vernünftig benennt oder dokumentiert kennt sich kein Schwein mehr aus, siehe WordPress! Die Verständlichkeit des Quelltexts leidet auch darunter weil man nicht mehr genau weiß was eine Methode macht ohne sich auch die Slots anzusehen.

… Licht und Schatten, aber bei WordPress funktioniert’s trotz der angesprochenen Probleme wunderbar. Jeder Entwickler kann aufgrund der vielen Signals (Actions) die eigene Logik in das Grundsystem integrieren ohne es anzugreifen. Und das Grundsystem bleibt damit weiterhin updatebar – voi cool gell!

Wikipedia: Signals and Slots
Wikipedia: AOP
Phly, boy, phly – Aspects, Signals, Filters
PHP Advent 2010 – AOD

Im Teil 2 wird der Erklärbär dann Aspect-Oriented Filters erklären … das wird wieder ein Spaß (oder?).