Erzeugung von Objekten

Das Singleton-Pattern ist ein in der Entwicklung weit verbreitetes Pattern. Es gehört zur Gruppe der Erzeuger-Pattern und wird vielfach deshalb eingesetzt um Informationen oder Funktionen von definierten Objekten innerhalb eines definierten Gültigkeitsbereichs zur Verfügung zu haben.

Das APF implementiert drei Formen des Patterns für unterschiedliche Gültigkeitsbereiche:

  • Singleton: Mit Hilfe dieser Implementierung lassen sich Objekte erzeugen, die innerhalb einer Anfrage eindeutig und einmalig sind. Mit jedem weiteren Request verlieren sie ihre Gültigkeit und die Klasse wird neu erzeugt.
  • SessionSingleton: Über diese Klasse lassen sich Objekte erzeugen, die innerhalb eines Besuchs (Session) gültig sind. Sobald die Session abgelaufen ist, verlieren sie ihre Gültigkeit und werden neu erzeugt.
  • ApplicationSingleton: Nutzen Sie innerhalb einer Anwendung Komponenten, die über mehrere Anfragen und Besuche hinweg nutzbar sind, so können Sie diese Implementierung zur Erzeugung Ihrer Objekte nutzen. Der Status wird so lange aufrecht erhalten, bis der Web-Server neu gestartet wird.
Bitte beachten Sie, dass die angegebenen Gültigkeitsbereiche nur dann erreicht bzw. eingehalten werden, wenn Sie die Klassen mit den oben genannten Implementierungen oder dem ServiceManager oder dem DIServiceManager erzeugen.
Die Nutzung der ApplicationSingleton-Implementierung setzt die PHP-Erweiterung APC voraus.
Bitte beachten Sie beim Einsatz von SessionSingleton und ApplicationSingleton die Serialisierungs-Mechanismen von PHP. Dies bedeutet beispielsweise, dass Resourcen (File-Pointer, Datenbank-Verbindungen) nicht searialisiert werden können und ggf. nach dem Wiederherstellen in einem weiteren Request neu initialisiert werden müssen.

Die oben aufgeführten Gültigkeitsbereiche lassen sich beim Entwurf einer Anwendung dazu einsetzen, gemeinsam genutzte Elemente (z.B. Business-Services, Anbindungen an Datenquellen oder externe Systeme) für unterschiedliche Teile der Software zu konfigurieren und zur Verfügung zu stellen. Dies trägt nicht nur zu einer besseren Performance bei, sondern ermöglicht auch die gemeinsame und für die Applikationsteile gekapselte Konfiguration und Initialisierung.

Das Adventure PHP Framework implementiert dabei das abstrakte Singleton Pattern und stellt zur Erzeugung die zuvor genannten Implementierungen bereit. Damit lassen sich im Gegensatz zum einfachen Singleton Pattern können beliebige Klassen in den verfügbaren Arten erzeugen, es bleibt jedoch gleichzeitig die Testbarkeit vollständig erhalten.

Die folgenden Kapitel zeigen Ihnen die Details zu den einzelnen Implementierungen auf und geben Beispiele und Hinweise für die Verwendung.

1. Singleton

Beabsichtigen Sie innerhalb einer HTTP-Anfrage eine eindeutige und einmalige Instanz einer Klasse zu nutzen, können Sie diese an allen benötigten Stellen via

PHP-Code
use APF\core\singleton\Singleton; use VENDOR\..\FooModel; $model = Singleton::getInstance('VENDOR\..\FooModel');

erzeugen und anschließend verwenden. Sollte die Instanz innerhalb der Anfrage noch nicht erzeugt worden sein, wird diese im Hintergrund angelegt und zurückgegeben. Sofern das Objekt bereits angefragt wurde, erhalten sie die bereits erzeugte Instanz.

Die Methode getInstance() erlaubt neben der Angabe der zu erzeugenden Klasse die Übergabe einer Instanz-Identifikation. Diese kann genutzt werden, wenn Sie innerhalb einer Applikation mehrere, gemeinsam genutzte Instanzen einer Klasse parallel zueinander nutzen möchten. Dies ist beispielsweise dann gegeben, wenn Sie Verbindungen zu mehreren Datenbanken über eine einzige Verbindungs-Implementierung tätigen wollen.

Die Anwendung gestaltet sich wie folgt:

PHP-Code
use APF\core\singleton\Singleton; use APF\core\database\MySQLiHandler; $connectionOne = Singleton::getInstance(MySQLiHandler::class, [], 'ConnOne'); $connectionTwo = Singleton::getInstance(MySQLiHandler::class, [], 'ConnTwo');

Die beiden Variablen $connectionOne und $connectionTwo beinhalten nun je eine Instanz der Klasse APF\core\database\MySQLiHandler, jedoch mit unterschiedlicher Instanz-Konfiguration (z.B. andere Datenbank).

Bitte beachten Sie, dass beim Bezug der jeweiligen Instanz (z.B. ConnOne) der zweite Parameter beim Aufruf der Methode getInstance() immer mitgegeben werden muss. Andernfalls erhalten Sie eine neue Instanz der Klasse.

Mit dem optionalen Argument $arguments (im vorangegangenen Beispiel leer übergeben) lassen sich Konstruktor-Argumente definieren, die bei der Erzeugung des Objektes an die Instanz übergeben werden. Aus Software-Design-Gesichtspunkten bietet das den Vorteil, dass Abhängigkeiten direkt über den Konstruktor ausgedrückt werden können.

Möchten Sie eine Instanz der Klasse

PHP-Code
namespace VENDOR\..\service; class WeatherService { public function __construct($url, DateTime $date) { ... } }

erzeugen und mit dem Werten http://api.openweathermap.org/data/2.5/weather (Argument $url) und 14.04.2014 (Argument $date) initialisieren, so lässt sich dazu folgender Code-Block nutzen:

PHP-Code
$service = Singleton::getInstance( 'VENDOR\..\service\WeatherService', [ 'http://api.openweathermap.org/data/2.5/weather', DateTime::createFromFormat('d.m.Y', '14.04.2015') ] );

Mit dem zweiten Argument der Methode getInstance() lassen sich beliebig viele Konstruktor-Argumente definieren.

Bitte beachten Sie, dass die Reihenfolge der Parameter bei der Übergabe an getInstance() mit der Reihenfolge der Parameter-Definition der zu erzeugenden Klasse übereinstimmt! Andernfalls kann es zu unerwarteten Fehlern kommen.
Die Erzeugung einer Instanz mit Konstruktor-Argumenten ist selbstverständlich auch mit der Vergabe einer Instanz-Identifikation kombinierbar.

2. SessionSingleton

Möchten Sie Informationen innerhalb eines Besuchs - als innerhalb einer HTTP-Session - Request-übergreifend speichern und nutzen, bietet sich die Erzeugung eines Daten-Behälters als SessionSingleton-Instanz an. Um beispielweise eine Instanz eines Models für einen mehrseitigen Workflow zu erzeugen, können Sie dieses an allen benötigten Stellen via

PHP-Code
use APF\core\singleton\SessionSingleton; use VENDOR\..\FooModel; $model = SessionSingleton::getInstance('VENDOR\..\FooModel');

erzeugen und anschließend verwenden. Sollte die Instanz innerhalb der Session noch nicht erzeugt worden sein, wird diese im Hintergrund angelegt und zurückgegeben. Sofern das Objekt bereits angefragt wurde, erhalten sie die bereits erzeugte Instanz. Damit lassen sich die Angaben eines Benutzers auf einem mehrseitigen Formular bequem speichern und am Ende des Workflows verarbeiten.

Die Methode getInstance() erlaubt neben der Angabe der zu erzeugenden Klasse die Übergabe einer Instanz-Identifikation. Diese kann genutzt werden, wenn Sie innerhalb einer Applikation mehrere, gemeinsam genutzte Instanzen einer Klasse parallel zueinander nutzen möchten. Dies ist beispielsweise dann gegeben, wenn Sie mehrere Workflows mit der gleichen Code-Basis innerhalb einer Anwendung nutzen können wollen.

Die Anwendung gestaltet sich wie folgt:

PHP-Code
use APF\core\singleton\Singleton; use VENDOR\..\FooModel; $modelOne = SessionSingleton::getInstance('VENDOR\..\FooModel', [], 'WorkflowOne'); $modelTwo = SessionSingleton::getInstance('VENDOR\..\FooModel', [], 'WorkflowTwo');

Mit dem optionalen Argument $arguments (im vorangegangenen Beispiel leer übergeben) lassen sich Konstruktor-Argumente definieren, die bei der Erzeugung des Objektes an die Instanz übergeben werden. Aus Software-Design-Gesichtspunkten bietet das den Vorteil, dass Abhängigkeiten direkt über den Konstruktor ausgedrückt werden können.

Möchten Sie eine Instanz der Klasse FooModel erzeugen und gleichzeitig initialisieren, so lässt sich dazu folgender Code-Block nutzen:

PHP-Code
$model = SessionSingleton::getInstance('VENDOR\..\FooModel', ['foo', 'bar']);

Mit dem zweiten Argumen der Methode getInstance() lassen sich beliebig viele Konstruktor-Argumente definieren.

Bitte beachten Sie, dass die Reihenfolge der Parameter bei der Übergabe an getInstance() mit der Reihenfolge der Parameter-Definition der zu erzeugenden Klasse übereinstimmt! Andernfalls kann es zu unerwarteten Fehlern kommen.
Die Erzeugung einer Instanz mit Konstruktor-Argumenten ist selbstverständlich auch mit der Vergabe einer Instanz-Identifikation kombinierbar.

3. ApplicationSingleton

Möchten Sie Informationen für alle Besucher und einmalig innnerhalb einer Applikation Request-übergreifend nutzen, so bietet sich die Erzeugung des Daten-Behälters als ApplicationSingleton-Instanz an. Diese Erzeugungsmethode ist beispielsweise dann interessant, wenn das Objekt aufwändig initialisiert werden muss, die Verwendung jedoch für alle Besucher und alle damit verbundenen Anfragen genutzt werden kann (z.B. Verbindung zu einer externen Schnittstelle wie einem Wetter-Dienst).

Um eine Instanz eines Services, der innerhalb einer kompletten Anwendung genutzt werden kann, zu erzeugen, ist folgender Code notwendig:

PHP-Code
use APF\core\singleton\ApplicationSingleton; use VENDOR\..\service\WeatherService; $service = ApplicationSingleton::getInstance('VENDOR\..\service\WeatherService');

Sollte die Instanz innerhalb der Applikation noch nicht erzeugt worden sein, wird diese im Hintergrund angelegt und zurückgegeben. Sofern das Objekt bereits angefragt wurde, erhalten sie die bereits erzeugte Instanz.

Die Methode getInstance() erlaubt neben der Angabe der zu erzeugenden Klasse die Übergabe einer Instanz-Identifikation. Diese kann genutzt werden, wenn Sie innerhalb einer Applikation mehrere, gemeinsam genutzte Instanzen einer Klasse parallel zueinander nutzen möchten. Dies ist beispielsweise dann gegeben, wenn Sie mehrere Verbindungen zu unterschiedlichen Wetter-Diensten über dieselbe Service-Implementierung realisieren möchten.

Die Anwendung gestaltet sich wie folgt:

PHP-Code
use APF\core\singleton\ApplicationSingleton; use VENDOR\..\WeatherService; $serviceOne = ApplicationSingleton::getInstance('VENDOR\..\service\WeatherService', [], 'ServiceOne'); $serviceTwo = ApplicationSingleton::getInstance('VENDOR\..\service\WeatherService', [], 'ServiceTwo');

Mit dem optionalen Argument $arguments (im vorangegangenen Beispiel leer übergeben) lassen sich Konstruktor-Argumente definieren, die bei der Erzeugung des Objektes an die Instanz übergeben werden. Aus Software-Design-Gesichtspunkten bietet das den Vorteil, dass Abhängigkeiten direkt über den Konstruktor ausgedrückt werden können.

Möchten Sie eine Instanz der Klasse WeatherService erzeugen und gleichzeitig initialisieren, so lässt sich dazu folgender Code-Block nutzen:

PHP-Code
$service = ApplicationSingleton::getInstance( 'VENDOR\..\service\WeatherService', [ 'http://api.openweathermap.org/data/2.5/weather', DateTime::createFromFormat('d.m.Y', '14.04.2015') ] );

Mit dem zweiten Argumen der Methode getInstance() lassen sich beliebig viele Konstruktor-Argumente definieren.

Bitte beachten Sie, dass die Reihenfolge der Parameter bei der Übergabe an getInstance() mit der Reihenfolge der Parameter-Definition der zu erzeugenden Klasse übereinstimmt! Andernfalls kann es zu unerwarteten Fehlern kommen.
Die Erzeugung einer Instanz mit Konstruktor-Argumenten ist selbstverständlich auch mit der Vergabe einer Instanz-Identifikation kombinierbar.

4. Weiterführende Kapitel

Basierend auf den in Kapitel 1 (Singleton), Kapitel 2 (SessionSingleton) und Kapitel 3 (ApplicationSingleton) beschriebenen Erzeugungs-Methoden bietet das APF weitere Hilfsmittel zur Erzeugung, Konfiguration und Verwaltung von Objekt-Instanzen an.

Der ServiceManager bietet eine Abstraktion der genannten Methoden an und hilft Ihnen bei der Konfiguration der erzeugten Objekte.

Der DIServiceManager ist ein Dependency-Injection-Container, der Ihnen hilft, Code und Konfiguration zu trennen, sowie durch Entkopplung der Komponenten Ihrer Anwendung die einfache Austauschbarkeit von Komponenten und deren Testbarkeit sicherzustellen.

Bei der Erstellung von komplexen Anwendungen wird empfohlen, vorrangig den DIServiceManager zur Erzeugung einzusetzen, da die oben aufgeführten Erzeugungs-Mechanismen keine Konfiguration der erzeugten Klassen anbieten.

Kommentare

Möchten Sie den Artikel eine Anmerkung hinzufügen, oder haben Sie ergänzende Hinweise? Dann können Sie diese hier einfügen. Die bereits verfassten Anmerkungen und Kommentare finden Sie in der untenstehenden Liste.
« 1   »
Einträge/Seite: | 5 | 10 | 15 | 20 |
1
Jan Wiese 04.11.2012, 12:07:54
Hallo Jens,

default wird der Modus SINGLETON angewendet.

LG :)
2
Jens Prangenberg 20.09.2012, 08:43:55
Hallo,
welcher {MODE} ist den Default?