Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > Pattern Singleton


Автор: MoLeX 9.2.2011, 12:42
Добрый день.

Есть несколько способов создание Singletonа

1. Singleton
Код

class Singleton {

  protected static $instance;

  private function __construct() {}
  private function __clone() {}

  public static function getInstance() {
    return (self::$instance === null) ?
        self::$instance = new self() :
        self::$instance;
  }

  public function doAction() {}
}


2. Singleton
Код

abstract class Singleton {
  private static $instances;

  final protected function __construct() {
  }

  final private function __clone() {
  }

  final public static function getInstance() {
    $class = get_called_class();
    if (!isset(self::$instances[$class])) {
      self::$instances[$class] = new $class;
    }
    return self::$instances[$class];
  }
}



Но помимо тех способах, есть еще:
3. Singleton
Код

function app( $class = null )
{
    static $obj = array();
            
    if( ! isset($obj[$class]) )
        $obj[$class] = new $class();
        
    return $obj[$class];
} 



Кто какой использует и почему?

Добавлено через 39 секунд
P.S. Навеяно обсуждением на http://habrahabr.ru/blogs/php/113418/#comments

Автор: Shogun 9.2.2011, 14:34
Второй, намного удобнее, но есть и нюансы.

Автор: ksnk 9.2.2011, 16:06
У меня почему-то получается третий. Он как-то ближе к PHP. Не в каждом языке можно писать скрытые глобальные переменные  smile Первые два - тяжелое наследие java. 
К тому-же по эффективности третий способ проигрывает только явным глобальным переменным. 

Автор: Muerto 9.2.2011, 19:05
Из тех вариантов что выше 2ой предпочитаю...

Автор: Dima 2015 9.2.2011, 19:10
Очень интересная тема. Сразу скажу, я не очень силен в ООП, но синглетон  как раз пытаюсь использовать. Судя по предложенному коду я использую 1й. И у меня возник вопрос как вообще применяются 2 и 3 способы? 
Способ 2 - это класс, который должен реализовывать синглетон наследуется от класса Singleton? А как быть если нужный класс должен быть унаследован еще от чего-нибудь, например от абстрактного юзера. Ведь в пхп нет множественного наследования...

Способ 3 - это что-то типа фабрик для объектов класса? Но тогда, раз мы можем написать $obj[$class] = new $class(); - то какой же это к черту синглетон. Если можно написать new $class - значит у него конструктор открыт..?

Проясните если несложно для начинающего разбираться в ООП smile

Автор: Shogun 9.2.2011, 21:29
Цитата(Dima 2015 @  9.2.2011,  19:10 Найти цитируемый пост)
Способ 2 - это класс, который должен реализовывать синглетон наследуется от класса Singleton?
 - ага

Цитата(Dima 2015 @  9.2.2011,  19:10 Найти цитируемый пост)
А как быть если нужный класс должен быть унаследован еще от чего-нибудь, например от абстрактного юзера.
Ну собственно это и есть тот минус такого метода, как решение сделать чтобы абстрактный класс юзера наследовался от синглетона, но это уже может привлечь другие проблемы или ограничения.

Цитата(Dima 2015 @  9.2.2011,  19:10 Найти цитируемый пост)
Способ 3 - это что-то типа фабрик для объектов класса? Но тогда, раз мы можем написать $obj[$class] = new $class(); - то какой же это к черту синглетон. Если можно написать new $class - значит у него конструктор открыт..?

Этот способ что-то вроде гибрида между factory и registry и в стиле пхп4 =))

Код
 if( ! isset($obj[$class]) ) $obj[$class] = new $class(); 
 - тут проверка для синглетона. 

Автор: Dima 2015 10.2.2011, 00:36
Shogun, понял спасибо. Все как я и думал.

Автор: MoLeX 10.2.2011, 06:23
ksnk, тоже использую третий. 
1 и 2 не понравились результатами теста, к ф-ции доступ всегда быстрее. Причем для второго способа надо PHP >= 5.3, из-за
Код

get_called_class();

Автор: SneG0K 10.2.2011, 23:13
Первый, иногда нужен конструктор

Добавлено через 1 минуту и 9 секунд
И второй работает только по-моему начиная с 5.3

Автор: Dima 2015 11.2.2011, 02:24
MoLeX, 
Цитата

к ф-ции доступ всегда быстрее

неужели это может быть ощутимо? Ну в плане нагрузки на сервер в посещаемом проекте..

Автор: MoLeX 11.2.2011, 06:41
может)

Автор: Shogun 11.2.2011, 15:44
Код

<?php

####################################
# 0.2836 - 0.3044
class App 
  {
    private static $instance;
    
    public static function instance()
      {
        return (!(self::$instance instanceof self) ? self::$instance = new self : self::$instance);
      }
      
    protected function __construct() {}
    final protected function __clone() {}
  }


####################################
# 0.5385 - 0.5548
abstract class Singleton
  {
    private static $instances = array();  
    
    final public static function instance()
      {
        $class = get_called_class();  
        
        return (!self::$instances[$class] ? self::$instances[$class] = new $class : self::$instances[$class]);
      }
  
    protected function __construct() {}
    final protected function __clone() {}
  }

class App extends Singleton {  }


####################################
# 0.2740 - 0.2941
function instance($class)
  {
    static $instances = array();
    
    return (!$instances[$class] ? $instances[$class] = new $class : $instances[$class]);
  }

class App 
  {
    public function __construct(){}
    final protected function __clone(){}
  }


####################################
# 0.2470 - 0.2615
function App()
  {
    static $instance;
    
    return (!$instance ? $instance = new App : $instance);
  }

class App 
  {
    public function __construct(){}
    final protected function __clone(){}
  }



####################################
$start = microtime(true);

for ($i=0; $i<10000; $i++)
  {
    #$app = App::instance();
    #$app = instance('App');
    #$app = App();
  }

$end = microtime(true);

$time = $end - $start;

echo '<br/><br/>Time: ', $time;


вроде так...

Цитата(Dima 2015 @  11.2.2011,  02:24 Найти цитируемый пост)
неужели это может быть ощутимо? Ну в плане нагрузки на сервер в посещаемом проекте.. 
 - сомневаюсь...

Автор: Dima 2015 11.2.2011, 16:37
MoLeX, сталкивался? Просто сразу тут возникает вопрос что за проект, как написан, какая посещаемость, какие сервера... а то все эти разговоры в пользу бедных. Я с трудом вообще представляю проект где сами пыхофункции будут тормозить...

Ну т.е. время работы самого пхп относительно времени получения данных с диска и вывода этих данных в браузер, оно обычно раз в 10 меньше. Т.е. у нас 0,001 сек выполняется пхп и 0,01 сек получаются данные из БД и выводятся в браузер (echo может быть долгим, ага). Так вот, ну выйграем мы 0.0005 сек за счет использования ф-ций вместо классов, вот радость то...

Автор: MoLeX 14.2.2011, 07:23
Dima 2015, все зависит от самого приложения. У нас очень много классов, при чем есть очень прожорливые классы. По тестам для нас выгодно использовать ф-цию, что мы и делаем

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)