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:
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.
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
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:
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).
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
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:
$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.
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
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:
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:
$model = SessionSingleton::getInstance('VENDOR\..\FooModel', ['foo', 'bar']);
Mit dem zweiten Argumen der Methode getInstance() lassen sich beliebig viele Konstruktor-Argumente definieren.
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:
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:
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:
$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.
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.
Um unsere Webseite für Sie optimal zu gestalten und fortlaufend verbessern zu können, verwenden wir Cookies. Durch die Nutzung der Webseite stimmen Sie der Verwendung von Cookies zu. Weitere Informationen finden Sie in den Datenschutzrichtlinien.