Erzeugungsmuster zur Erstellung genau EINER Instanz eines Objekts. Weitere Instanzen oder Klonen des Objects soll verhindert werden.
z.B Zend_Auth
* Singleton instance
*
* @var Zend_Auth
*/
protected static $_instance = null;
/**
* Singleton pattern implementation makes "new" unavailable
*
* @return void
*/
protected function __construct()
{}
/**
* Singleton pattern implementation makes "clone" unavailable
*
* @return void
*/
protected function __clone()
{}
/**
* Returns an instance of Zend_Auth
*
* Singleton pattern implementation
*
* @return Zend_Auth Provides a fluent interface
*/
public static function getInstance()
{
if (null === self::$_instance) {
self::$_instance = new self();
}
return self::$_instance;
}
DebuggerEcho (komplexeres Bsp)
namespace de\phpdesignpatterns\util\debug;
require_once 'Debugger.php';
class DebuggerEcho implements Debugger {
// in einer statischen Eigenschaft wird die Instanz gespeichert
private static $instance = null;
// getInstance soll die einzige Funktion sein, durch die
// eine Instanz erzeugt werden kann
public static function getInstance() {
if (self::$instance == null) {
self::$instance = new DebuggerEcho();
}
return self::$instance;
}
// durch die protected-Deklaration wird der Konstruktor von außen unerreichbar
// dadurch kann durch den new-Operator keine weitere Instanz erzeugt werden
protected function __construct() {
}
// durch die private-Deklaration wird das
// Klonen bereits vorhandener Instanzen verhindert
private function __clone() {}
public function debug($message) {
echo "{$message}\n";
}
}
$debuggerObi = DebuggerEcho::getInstance();
$debuggerObi->debug('Nutze die Macht, Luke!');
// $debuggerVader = clone $debuggerObi; // erzeugt Fatal error !
$debuggerVader = DebuggerEcho::getInstance();
$debuggerVader->debug('Luke, ich bin Dein Vater!');
if ($debuggerObi === $debuggerVader) {
echo "Die beiden Debugger sind das selbe Objekt.\n"; // wird ausgegeben
} else {
echo "Die beiden Debugger sind *NICHT* das selbe Objekt.\n";
}
Ausgabe mit PHP 5.3 (wichtig wg. Namespace-Deklaration!):
Nutze die Macht, Luke!
Luke, ich bin Dein Vater!
Die beiden Debugger sind das selbe Objekt.
Das Debugger-Interface schreibt nur eine Funktion vor (debug):
namespace de\phpdesignpatterns\util\debug;
interface Debugger {
public function debug($message);
}
Ausgabe mit PHP 5.3 (wichtig wg. Namespace-Deklaration!):
Nutze die Macht, Luke!
Luke, ich bin Dein Vater!
Die beiden Debugger sind das selbe Objekt.
Das Debugger-Interface schreibt nur eine Funktion vor (debug):
Variation: DebuggerLog
Singleton-Pattern parametrisiert. Es sollen abhängig von einem Parameter jeweils nur eine Instanz / Parameter zugelassen werden. Hier: der Name der Log-Datei wird übergeben. Wenn bereits eine Instanz für die Log-Datei existiert, sollen keine weiteren erzeugt werden. Lösung: die Klasseneigenschaft $instance wird als Array definiert.
namespace de\phpdesignpatterns\util\debug;
require_once 'Debugger.php';
class DebuggerLog implements Debugger {
protected $logfile = null;
// statische Klasseneigenschaft als Array
private static $instances = array();
// pro Parameter (Logfile) soll nur eine Instanz zugelassen werden
public static function getInstance($logfile) {
if (!isset(self::$instances[$logfile])) {
self::$instances[$logfile] = new DebuggerLog($logfile);
}
return self::$instances[$logfile];
}
protected function __construct($logfile) {
$this->logfile = $logfile;
}
private function __clone() {}
public function debug($message) {
error_log("{$message}\n", 3, $this->logfile);
}
}
$debuggerObi = DebuggerLog::getInstance('./obi.log');
$debuggerObi->debug('Nutze die Macht, Luke!');
$debuggerVader = DebuggerLog::getInstance('./vader.log');
$debuggerVader->debug('Luke, ich bin Dein Vater!');
if ($debuggerObi === $debuggerVader) {
echo "Die beiden Debugger sind das selbe Objekt.\n";
} else {
echo "Die beiden Debugger sind *NICHT* das selbe Objekt.\n";
}