В этом паттерне название говорит само за себя, singleton(single = единственный).
Т.е. паттерн должен реализовывать функционал единоразового создания обьекта.
Для чего это надо ? А для того чтобы не плодить обьекты.
Итак рассмотрим типичный пример синглтона :
<?php
class NRG_Singleton
{
// переменная в которой мы будем хранить сущность текущего класса
private static $instance;
// конструктор обьявлен приватным для того чтобы избежать попытки прямого создания обьекта
private function __construct()
{}
// метод который реализовует всю логику
public static function singleton()
{
if (!isset(self::$instance)) {
$c = __CLASS__;
self::$instance = new $c;
}
return self::$instance;
}
// для особо хитрожопых
public function __clone()
{
trigger_error('Нельзя. Онотоле не одобрям.', E_USER_ERROR);
}
}
Даный пример кода позаимствован с мана
http://www.php.ru/manual/language.oop5.patterns.html#language.oop5.patterns.singleton
В этом примере все просто. Обьект NRG_Singleton мы можем создать только через вызов статического метода singleton(). И суть данного метода в том что «реально» обьект создастся только один раз ( при самом первом вызове метода singleton() ), а все последующие разы метод будет возвращать уже готовый обьект.
Registry
Ну по названию этого паттерна я думаю что тоже не сложно догадаться что он делает. =)
Ну а для тех кто всетаки не догадался, то скажу по секрету, он регистрирует.
Вот типичный примерчик для такого паттерна:
<?php
class NRG
{
// наше чудо-хранилище
static private $_registry = array();
// чудо-метод который извлекает данные из хранилища
public static function registry($key)
{
return (isset(self::$_registry[$key])) ? self::$_registry[$key] : null;
}
// чудо-метод который добавляет данные в хранилище
public static function register($key, $value)
{
self::$_registry[$key] = $value;
}
// удаление данных из хранилища
public static function unregister($key)
{
if (isset(self::$_registry[$key])) {
if (is_object(self::$_registry[$key]) && (method_exists(self::$_registry[$key], '__destruct'))) {
self::$_registry[$key]->__destruct();
}
unset(self::$_registry[$key]);
}
}
}
Ну и что мы здесь видим ?
Все наши пряники лежат в хранилище $_registry. Попадают они туда благодаря методу register(), который просто невероятным(почти волшебным) способом их туда складывает.
Метод registry() получает данные, а метод unregister() их оттуда удаляет.
Кстати, может кто-то из вас уже догадался, но реализацию паттерна синглтон можно впихнуть сюда, что как по мне будет правильнее.
Т.е. нам не надо при создании класса думать о том будет ли он использоватся как синглтон или нет, и плюс мы сэкономим чуток места, за счет того что опишем функционал синглтона всего лишь в одном месте.
А сделаем мы всю эту прелесть очень просто, все что нам нужно, это добавить один метод в класс NRG , и выглядеть он будет так:
public static function getSingleton($modelClass='')
{
$registryKey = '_singleton/'.$modelClass;
if (!self::registry($registryKey)) {
self::register($registryKey, new $modelClass);
}
return self::registry($registryKey);
}
Вот вам и все пряники! =)
Factory
Ну тут тоже ничего сложного, непонимаю почему, но многие боятся этого паттерна(имею ввиду новичков). Просто надо найти ему применение.
Рассомотрим пример:
<?php
class NRG
{
// наша фабрика
public static function factory($type)
{
if (include_once(' lib/Database/Driver/' . $type . '.php')) {
$classname = 'Database_Driver_' . $type;
return new $classname;
} else {
throw new Exception ('Driver not found');
}
}
}
// пробуем подгрузить дравйвера
$mysql = NRG::factory('Mysql');
Даный пример кода позаимствован с мана
http://www.php.ru/manual/language.oop5.patterns.html#language.oop5.patterns.factory
В даном методе все работает чересчур просто. В зависимости от входящего параметра мы подключаем нужный нам драйвер. Т.е. если на вход(как в примере) прийдет Mysql, то сначала мы попытаемся заинклудить файл в котором описан сам класс драйвера (lib/Database/Driver/Mysql.php) , если не получилось, то трубим во все трубы и говорим что наш драйвер не найден. Иначе мы создаем инстанс Database_Driver_Mysql и возвращаем его.
Надеюсь все описал просто, кратко и понятно.
Если есть вопросы, то не стесняйтесь)))
Всем чмоки.