Одиночка (Singleton) — шаблон проектирования
15 января 2020
Шаблон используется в случаях, где требуется только один объект класса и нужно иметь общую точку доступа к этому объекту.
Шаблон состоит из следующих элементов:
Пример использования шаблона на языке PHP. Тут определён класс DB с методом getInstance для получения объекта. Весь смысл шаблона заключается в том, чтобы имелся только один объект класса.
Скрипт, в котором выполняется проверка, что две переменные объекта ссылаются на один и тот же участок памяти. Проверка выполняется с помощью оператора ===, который для объектов сверяет адреса памяти.
Результатом работы скрипта будет вывод сообщения:
Пример задачи: реализация работы с БД. Создаётся единственный объект для подключения к базе и выполнения запросов, причём доступ к объекту должен иметься из любого места кода.
Шаблон состоит из следующих элементов:
- Приватный конструктор — объявляется как приватный, для запрета на создание новых объектов данного класса;
- Статическое свойство — для хранения объекта класса;
- Статический метод — возвращает единственный объект класса. Метод часто именуют getInstance.
Пример использования шаблона на языке PHP. Тут определён класс DB с методом getInstance для получения объекта. Весь смысл шаблона заключается в том, чтобы имелся только один объект класса.
<?
final class DB
{
/**
* Свойство, которое хранит объект класса
*/
private static $instance = null;
/**
* Создаёт объект класса
* @return DB
*/
public static function getInstance()
{
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Делаем конструктор приватным, чтобы его нельзя было вызывать за пределами определния класса.
* Для получения объекта класса нужно вызывать метод DB::getInstance()
*/
private function __construct()
{}
/**
* Делаем магический метод __clone приватным, чтобы нельзя было создать новые объекты класса, используя клонирование
*/
private function __clone()
{}
/**
* При срабатывании магического метода __wakeup (метод пробуждения, выполняется автоматически при десериализации
* через unserialize) порождаем ошибку с сообщением о невозможности создания данным образом объекта класса DB
*/
public function __wakeup()
{
throw new Exception("Нельзя выполнить десериализацию объекта класса DB");
}
}
?>
Скрипт, в котором выполняется проверка, что две переменные объекта ссылаются на один и тот же участок памяти. Проверка выполняется с помощью оператора ===, который для объектов сверяет адреса памяти.
<?
//Подключение класса DB для работа с БД
require_once(__DIR__.'/DB.class.php');
$DB1 = DB::getInstance();
$DB2 = DB::getInstance();
if ($DB1 === $DB2) {
echo 'Переменные $DB1 и $DB2 ссылаются на один и тот же участок памяти';
} else {
echo 'Переменные $DB1 и $DB2 ссылаются на РАЗНЫЕ участки памяти';
}
?>
Результатом работы скрипта будет вывод сообщения:
Переменные $DB1 и $DB2 ссылаются на один и тот же участок памяти