Приветствую Вас, читатель моего блога! Первая статья из цикла паттерны проектирования посвящена очень полезному шаблону - singleton. Почему я решил начать именно с него? Всё очень просто, этот шаблон является первым шаблоном который я начал использовать в практической разработке и сразу же ощутил всю его мощь. Относится данный шаблон к шаблонам порождающим объекты или к шаблонам генерации объектов. Итак, перейдём к делу...
Описание
Шаблон singleton позволяет создавать лишь один экземпляр класса в течении работы приложения. Это даёт ряд преимуществ:
- Глобальный доступ к объекту
- Уверенность в том что есть только один экземпляр класса
- Контроль доступа к данным
Я думаю каждый понимает, что использование глобальных переменных вредит качеству кода. Глобальные переменные создают ряд проблем:
- Засоряют область видимости
- Их можно случайно затереть
- Не инкапсулируют доступ к данным
- Тяжело отслеживать их доступность на разных уровнях приложения
При использовании рассматриваемого шаблона вместо глобальных переменных мы избавляемся от всех вышеописанных проблем. Таким образом одиночка является улучшенной версией глобальных переменных. Но здесь тоже не всё так просто, злоупотреблять использованием данного шаблона нельзя, т.к. это приводит к сильной зависимости других классов и может привести к появлению непонятных, скрытых каналов данных.
Реализация
Реализация данного шаблона очень простая и сводится к созданию закрытого конструктора, хранения экземпляра класса в статической переменной класса и организации доступа к объекту через статический метод класса. Пример шаблона одиночка:
<?php
// ...
class Singleton{
//Экземпляр объекта Singleton
static protected $instance = null;
//Метод предоставляет доступ к объекту
static public function getInstance(){
if (is_null(self::$instance))
self::$instance = new Singleton();
return self::$instance;
}
//Закрытый конструктор
private function __construct(){
echo 'New instance!' . "\n";
}
private function __clone(){}
public function someAction(){
echo 'Some action!' . "\n";
}
}
Как Вы видите здесь всё очень просто, конструктор объявлен как private метод, для того чтобы создавать экземпляр можно было только из методов класса. Экземпляр класса хранится в приватной статической переменной $instance и доступ к нему осуществляется через открытый статический метод getInstance. Теперь рассмотрим, как применять данный класс:
<?php
// ...
Singleton::getInstance()->someAction();
Singleton::getInstance()->someAction();
В результате получаем следующий вывод:
New instance!
Some action!
Some action!
Как Вы видите конструктор вызывается только 1 раз для 2х вызовов метода getInstance.
Применение
Применять данный шаблон можно для многих задач. Наиболее часто он применяется для следующих целей:
- Осуществление доступа к данным или функционалу на различных уровнях приложения. Например абстракция над http запросом и осуществление доступа к нему из контроллеров и видов приложения (для MVC архитектуры)
- Абстракция над доступом к ресурсам. Например, контроль за тем чтобы в приложении создавался всего одно соединение с базой данных, ресурс которого сохраняется в объекте-одиночке.
Это только некоторые способы применения данного шаблона. На этом всё. Буду рад ответить на ваши вопросы по данной теме.