Seite wählen

Man reiche mir einen Pimple!

von | Mrz 1, 2012 | Development

Die genaue Übersetzung des Begriffes „Pimple“ ist eher unappetitlich und hat auch nichts mit einem fränkischen Gummistöpsel zum reinigen von Toiletten oder ähnlichem zu tun. Es handelt sich eher um einen Dependency Injection (DI) Container für PHP5.3 welcher dafür zuständig ist, Objekte für den Gebrauch in der Applikation bereitzustellen und an einer zentralen Stelle aufzubewahren.
DI ist ein Entwurfsmuster und zielt damit auf ein Paradigma aus der objektorientierten Programmierung ab, welches eine „Steuerungsumkehr“ vorschreibt (IoC = Inversion of Control). Mit diesem Muster baut eine Klasse seine Abhängigkeit nicht selbst sondern bekommt diese injiziert. Damit muss die Klasse die konkrete Implementierung nicht selbst kennen, lediglich die darauf aufbauende Schnittestelle.
Ein Beispiel aus der Zeit wo Mark Zuckerberg noch Erich Mielke hieß:

store = new SessionStorage("DING");
        }
        public function writeToDump() {
                $this->store->store((array) $this);
        }
        public function __destruct() {
                $this->writeToDump();
        }
}
class User {
        public function __construct() {
                $this->session = new Session();
                $this->session['authenticated'] = false;
        }
        public function setAuthenticated() {
                $this->session['authenticated'] = true;
        }
}

Diese Vorgehensweise wird zum Problem wenn die Klasse „Session“ öfters verwendet wird – und das wird der Fall sein. Man kann sie nicht einfach ersetzen. Entweder schmeißt man die bisherige Implementierung über Board oder muss im kompletten Code die Handhabung anpassen um mit der neuen Implementierung umzugehen. Idealer Anwendungsfall sind UnitTests. In diesem Fall könnte man eine Dummy-Session schreiben (Mock-Objekt) welche die Daten einfach verwirft, da dies für den Test nicht relevant ist (Oder zum Fehler führt da in der Testumgebung eventuell kein valider Cookie Container existiert).
Um dem Herr zu werden bauen wir das ganze um und geben die Implementierung mit (Constructor Injection):

store = $s;
        }
        public function writeToDump() {
                $this->store->store((array) $this);
        }
        public function __destruct() {
                $this->writeToDump();
        }
}
class User {
        public function __construct(ISession $session) {
                $this->session = $session;
                $this->session['authenticated'] = false;
        }
        public function setAuthenticated() {
                $this->session['authenticated'] = true;
        }
}

Jetzt muss beim instantiieren immer ein gültiges Session Objekt mit zugegeben werden was „einiges“ an Verdrahtungsarbeitet kostet. Die Implementierung kann aber leichter ausgetauscht werden. Konfigurierbar ist dieses Vorgehen aber noch nicht und kostet daher weiterhin Wartungsaufwand wenn Änderungen durchgeführt werden müssen.
Jetzt wird es Zeit für Pimple. Wir konfigurieren uns einen Container und kleben die Implementierung zur Laufzeit zusammen:

$session = new Pimple();
// Konfigurationsanteil
$session['cookie_name'] = 'DING';
$session['session_storage_class'] = 'SessionStorage';
$session['session_class'] = 'Session';
$session['session_storage'] = function($c) {
        return new $c['session_storage_class']($c['cookie_name']);
};
$session['session'] = $session->share(function($c) {
        return new $c['session_class']($c['session_storage']);
});

Zwecks besserer Übersicht sind die Schnittstellen und Klassen raus gelassen. Mit dem obigen Beispiel kan man zur Laufzeit alles erdenkliche steuern und die Container-Klasse als Provider beliebig in der Applikation verwenden. Für eine neue Session oder einen Storage-Provider, tauscht man die Implementierung per Konfiguration aus – fertig!
Man könnte sogar noch weiter gehen und die Konfiguration in XML oder INI Dateien verpacken. Allerdings mit dem Nachteil in der Konfiguration zu „programmieren“ was das Konstrukt zerreist und bei großen Projekten zur Unübersichtlichkeit führt.
Bei Compilersprachen wird dieses Feature für mehr Flexibilität benutzt um Austauschbarkeit zur Laufzeit zu erreichen. Bei Scriptsprachen hingegen gibt es oft eigene (sehr eigene ;-)) Möglichkeiten, Methoden zu überschreiben oder irgendwelche Wrapper einzubinden.
Natürlich ist DI nicht die einzige Möglichkeit. Einige dieser Patterns, z.B. „Service/Locator“, „Observer“, Fasaden, … zielen auf IoC ab. Auch Singletons könnte man dazu zählen – Sollte man aber nicht.
Natürlich ist alles nicht immer nur mit Vorteilen verbunden. Man muss also genau abwägen in wie weit einem dies nützt und bei der Durchführung eines Projekts unterstützt. Auch darf man es, wie bei allen Pattern, nicht zu sehr übertreiben. Für die Ausgabe von drei Zeilen Text muss ich keine 20 Paradigmen aufgreifen um guten Code zu schreiben.
Die positive Seite der Medaille: Der Code wird wandelbarer und damit leichter zu warten!

Pimple – Inversion of ControlSubstrate – PHP5/SPL

Marius Hein
Marius Hein
Head of IT Service Management

Marius Hein ist schon seit 2003 bei NETWAYS. Er hat hier seine Ausbildung zum Fachinformatiker absolviert und viele Jahre in der Softwareentwicklung gearbeitet. Mittlerweile ist er Herr über die interne IT und als Leiter von ITSM zuständig für die technische Schnittmenge der Abteilungen der NETWAYS Gruppe. Wenn er nicht gerade IPv6 IPSec Tunnel bohrt, sitzt er daheim am Schlagzeug und treibt seine Nachbarn in den Wahnsinn.

0 Kommentare

Trackbacks/Pingbacks

  1. Weekly Snap: Pimple for PHP, Jobs, RootCamp & CeBIT › NETWAYS Blog - [...] ailments aside, Marius introduced Pimple and its merits as a dependency injection container for PHP 5.3. Tobias then followed with…
  2. Mockups, Mockups, wer braucht Mockups? › NETWAYS Blog - [...] Auch beim Testen kommen Mock-Objekte zum Einsatz. Tests können so mit unechten Datenbankobjekten umgehen – Eine Art Hülle, unter…
  3. GRAV, ein schnelles, dateibasiertes, einfaches CMS – Blog - […] wird auf Doctrine Cache zurückgegriffen, für die Wartbarkeit und Erweiterbarkeit auf Pimple (Was ist Pimple?). Der Symfony Event Dispatcher…

Einen Kommentar abschicken

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Mehr Beiträge zum Thema Development

Mein PHP-Trainingsprojekt

PHP Schulung Vor kurzem haben wir begonnen, eine neue Programmiersprache zu lernen – PHP. In der ersten Woche haben wir mit den Grundlagen wie Variablen, Arrays, Schleifen begonnen und uns schrittweise zu komplizierterer Syntax wie Funktionen, Objekten und Klassen...

check_prometheus ist jetzt öffentlich verfügbar!

Monitoring ist komplex, das wissen wir hier bei NETWAYS leider zu gut. Deswegen laufen in der Infrastruktur auch mal gerne mehrere Tools für die Überwachung. Zwei gern gesehene Kandidaten sind dabei Icinga und Prometheus. Icinga und Prometheus erfüllen...