Паттерн Singleton

Эта статья будет первой из раздела “Профессиональный php” и начнет она в нем тему шаблонов проектирования. Если простыми словами, то шаблон проектирования это код, который решает какую-то задачу, с которой программисты часто сталкиваются (задача реализации какой-то логики). Если сейчас не понятно, то дальше поймете, на примерах.

Начну я, как и все, с шаблона Singleton (“одиночка”, если по-русски). Но, сначала, небольшое отступление. Если Вы заходили на сайт блога, то могли заметить – справа появилось голосование. У меня просьба ко всем читателям нашего блога – оставить там свое мнение, ведь от его результатов будет зависеть направление развития блога. Спасибо :)

Теперь продолжу про singleton. Как я уже заметил выше, назначение каждого шаблона – это решение какой-то задачи.

Задачи.

Шаблон проектирования Singleton решает сразу две задачи:

  1. Обеспечивает возможность существования только одного экземпляра класса
  2. Предоставляет глобальный доступ к этому экземпляру

Выявление мест, для применения шаблонов проектирования, не такая уж очевидная задача. Исходя из задач, которые призван решать singleton, давайте подумаем - где его можно применить?

Начать лучше со второй задачи – глобализация объекта. На практике, часто приходится сталкиваться с ситуациями, в которых необходимо использовать глобальные переменные. Например, конфиг, в котором хранятся настройки всего приложения, а значит, обращаться к ним приходится из самых разнообразных мест программы.

Что касается второй задачи, то давайте предположим, что реализуем приложение-государство. В каждом государстве в любой промежуток времени может быть только один президент. Следовательно, для президента можно применить шаблон Singleton.

Реализация.

Реализация шаблона проектирования Singleton выглядит следующим образом:

class Singleton {
  // object instance
  private static $instance;
  private function __construct() {}
  private function __clone() {}
  public static function getInstance() {
    if (self::$instance === null) {
      self::$instance = new self;
    }
    return self::$instance;
  }
  public function doAction() {
    ...
  }
}

После этого, к экземпляру этого класса можно будет обращаться из любой точки программы вот так:

Singleton::getInstance()->doAction();

Кроме того, такая реализация не позволяет создать новый экземпляр этого класса, либо клонировать текущий.

Предостережения

Несмотря на достаточную простоту этого шаблона, не стоит терять бдительности, так как при неправильном применении, он может существенно подпортить программу в будущем.
Дело в том, что большинство программ имеют тенденцию расширять свой функционал, а объект-singleton будет на протяжении всего развития проекта “гвоздем” в нем.

Он не позволит в будущем создавать второй экземпляр этого класса, даже если он пригодится. Вот тогда-то придется рефакторить проект очень долго, чтобы такую возможность добавить. Поэтому, прежде чем применять этот шаблон, убедитесь, что ваша системе точно не будет расширяться в этом направлении.





Читайте также:



5 Ответов на “Паттерн Singleton”

  1. Игорь

    Хороший пост

  2. Одна из самых уродливых релизаций.
    Для создания объектов классов удобнее создать ссылочную функцию, подргружающую класс из файла, инстанцирующую объект и возвращающую ссылку на элемент статического массива-контейнера, в котором хранятся все объекты.
    Не надо будет засорять классы ненужным кодом…
    Итого, Singleton и Lazy Loading в одном флаконе…

  3. cryptus

    То что ты сказал - это почти что шаблон проектирования Registry. Я еще о нем напишу статью. А здесь представлена стандартная реализация шаблона Singleton и все остальное что ты описал к нему не относится. Хотя идея неплохая конечно, но Registry предлагает даже бОльшие возможности, чем те, которые ты описал.

  4. Я ещё активно использую псевдосинглетон.
    Как то:
    class Singleton {
    private static $instance = array();
    private function __construct() {}

    public static function getInstance($key) {
    if (!key_exists($key, self::$instance)) {
    self::$instance[$key] = new self;
    }
    return self::$instance[$key];
    }
    }

    Т.е. реализация объекта зависит от ключа $key.

  5. “шаблон проектирования это код”
    скорее подход или прием к решению проблемы


© Copyright. . I-Novice. All Rights Reserved. Terms | Site Map