Welcome to php club

Singleton (Единственный экземпляр)


Назначение:
Создание единственного экземпляра класса. В любой точке программы при работе с singleton вы будете работать с одним и тем же экземпляром класса.


Определение GoF?:
Убедится, что класс имеет только один экземпляр и предоставить глобальную точку доступа к нему.


Применяется в случае:

  1. Если существует необходимость создать единственный экземпляр класса
  2. В контексте PHP, в скриптах может применяться как замена глобальных переменных

Реализация:
Для реализации шаблона Singleton необходимо создать класс, имеющий статический аттрибут, ссылающиеся на экземпляр этого класса ($instance). Кроме того, класс должен содержать статический метод, возвращающий существующий экземпляр класса, если он уже был создан, или создающий новый экземпляр и сохраняющий его в аттрибут $instance. Кроме этого, необходимо объявить конструктор класса как private (для того чтобы гарантировать создание только одного экземпляра).


PHP4
Реализация для PHP4 в полной мере невозможна из-за отсутствия модификаторов области видимости (private, protected, public). Однако четко придерживаясь соглашений о кодировании использовать данный шаблон возможно.
Код может быть примерно таким:

class Singleton
{

  /**
   * @static 
   * @access public
   * @example Для создания экземпляра этого класса используйте Singleton::getInstance(): $class = Singleton::getInstance();
   * @example НЕ ИСПОЛЬЗУТЕ ОПРЕТОР new, СЛЕДУЮЩИЙ КОД НЕПРАВИЛЬНЫЙ: $class = new Singleton ( );
   */
  function &getInstance ( )
  {
    static $instance = null;
    
    if ( (isset($this)) && (get_class($this) == __CLASS__) )
        trigger_error("Статический метод класса ".__CLASS__."::".__FUNCTION__."() вызван как не статический",E_USER_ERROR);

    
    if ( is_null ( $instance ) )
    {
      $instance = array ( );  //дружно благодарим Андрея Сухачева (компания "Информ-Мобил")
      $instance[0] = & new Singleton( null );  // за ценное замечание с использованием массива
    }
    return $instance[0];
  }
  
  /**
   * @access private
   * Конструктор без параметров (если вам нужны параметры добавьте их перед параметром $instance)
   * Пытаемся обойти отсутсвие модификаторов области видимости в PHP4 используя параметр $instance
   * Этот прием используем как защиту от случайных ошибок
   */
  function Singleton ( $instance = "fake" )
  {
       
     if (!is_null($instance))
        trigger_error("Нельзя использовать конструтор для создания класса Singleton. 
                           Используйте статический метод getInstance ()",E_USER_ERROR);

        //TODO: Добавьте основной код конструктора здесь

  }

    //Тут следует основной код класса

}

// ===========================================================================
// Другой вариант без массива подсказанного Андреем Сухачевым (компания "Информ-Мобил") 8-)
// -------------------------------------------------------------------------------------------------
/**
* @example Для создания экземпляра этого класса используйте 
* @example Singleton::getInstance(): $object =& Singleton::getInstance();
* @example НЕ ИСПОЛЬЗУТЕ ОПРЕТОР new, 
* @example СЛЕДУЮЩИЙ КОД НЕПРАВИЛЬНЫЙ: $object = new Singleton ( );
*/
class Singleton
{

    function Singleton($directCall=true)
    {
        if ($directCall) {
            trigger_error("Нельзя использовать конструтор для создания класса Singleton. 
                           Используйте статический метод getInstance ()",E_USER_ERROR);
        }
        //TODO: Добавьте основной код конструктора здесь
    }

    function &getInstance()
    {
        static $instance;
        if (!is_object($instance)) {
            $instance = new Singleton(false);
        }
        return $instance;
    }
}


PHP5
Для PHP5 реализация выглядит проще:

class Singleton
{
    private static $instance = null;
    
    public static function getInstance ( )
    {
        if ( is_null ( self::$instance ) )
        {
            self::$instance = new Singleton ( );
        }
        
        return self::$instance;
    }
    
    private function __construct( )
    {
        //TODO: Код конструктора здесь
    }

    private function __clone ( )
    {
        // Конструктор копирования нам не нужен
    }
    
    //Тут следует основной код класса
}


Для получения экземпляра класса Singleton в PHP4 используется следующая конструкция (поправка Бориса Безрукова aka Lovchy):

$Object = & Singleton::getInstance();


Для получения экземпляра класса Singleton в PHP5 используется следующая конструкция:

$Object = Singleton::getInstance();


 
Много комментариев (4). [Показать комментарии/форму]