Singleton (одиночка)

Приветствую Вас, читатель моего блога! Первая статья из цикла паттерны проектирования посвящена очень полезному шаблону - 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.

Применение

Применять данный шаблон можно для многих задач. Наиболее часто он применяется для следующих целей:

Это только некоторые способы применения данного шаблона. На этом всё. Буду рад ответить на ваши вопросы по данной теме.