Singleton и наследование

FractalizeR

Новичок
Вообще-то Singleton и наследование мне кажутся несовместимыми.

http://www.codeguru.com/forum/showthread.php?p=1337660

реестр умеет только хранить данные. сам инстанциировать объекты по имени он не должен. если он создаёт объекты (по факту - становится порождающим паттерном), то он автоматически превращается в фабрику :)
А нельзя ли фабрику попросить стать и реестром тоже? :) Я так понимаю, есть два варианта.

Либо иметь фабрику, создающую сингтоны (http://en.wikipedia.org/wiki/Singleton_pattern#Example_of_use_with_the_factory_method_pattern, при этом функционал, делающий класс синглтоном будет дублироваться во всех синглтонах), либо иметь фабрику, включающую в себя реестр, которая будет создавать обычные объекты, но в одном экземпляре и при повторном запросе отдавать уже созданный объект.
 

Adelf

Administrator
Команда форума
zerkms согласен :) Поглядел пару источников. Получается мешанина из Фабрик(или Одиночек) и Реестра. Кое-где это названо одной из разновидностей реестра. Да по барабану как это назвать :)
 

zerkms

TDD infected
Команда форума
А нельзя ли фабрику попросить стать и реестром тоже? Я так понимаю, есть два варианта.
можно. тогда это будет 2 взаимодействующих паттерна. один строит объекты, другой предоставляет доступ к референсам. и всё это будет скрыто за одним общим интерфейсом. м?
 

partizan

Новичок
Да уже проще после описания каждого класса сразу создавать экземплер в глобальную переменную, и его использовать.

Или что-то типа такого:

PHP:
function getSingletonInstance($class_name)
{
 if (empty($GLOBALS["singleton_instance_of_$class_name"]))
 {  
   $GLOBALS["singleton_instance_of_$class_name"] = new $class_name;
 }
 return $GLOBALS["singleton_instance_of_$class_name"];
}
Вот только согласитесь, запись
PHP:
 $a = MyClass::getInstance();
изящнее смотрится, чем
PHP:
 $a = getSingletonInstance('MyClass');
 

zerkms

TDD infected
Команда форума
partizan
убери GLOBALS пока никто не увидел. я же писал - статический массив

function ...() {

static $instances;

if (!isset($instances[$class])) ...

ps: чем изящнее?

myClass::getInstance();

vs

getInstance('myClass');

нету ::, есть '
в чём ещё разница?
 

Adelf

Administrator
Команда форума
zerkms ну если тока phpDoc и красивые подсказки от IDE :)
 

zerkms

TDD infected
Команда форума
Adelf
ага, IDE взяла и разбежалась разрулить LSB. нуну :)

(я писал фразу исходя из посыла, что в пхп 5.2 у нас такое колдунство работать не будет, а в 5.3 у нас подзнее связывание, которое происходит в рантайме)
 

Adelf

Administrator
Команда форума
Я не знаю что такое LSB.
Eclipse подсказывает когда знает что за класс и этот класс находится в данном проекте. С фабрико-реестром соответственно ничего не подскажет.
 

zerkms

TDD infected
Команда форума
Adelf
Late Static Binding

В этом топике обсуждается возможность создания касса-предка синглтона. Так вот, это возможно в 5.3 с помощью механизма позднего связывания. И для таких ситуаций IDE не сможет подсказать тебе класс, потому как связывание происходит в рантайме.

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

м?
 

partizan

Новичок
Автор оригинала: zerkms
в чём ещё разница?
Да просто когда задача такая возникла (класс с единственным экземпляром), понятно, что варинтов можно много придумать. Но вот вспомнил, как на экзамене эту тему сдавал - решил хоть раз высшее образование на практике применить :)

Автор оригинала: Adelf
zerkms ну если тока phpDoc и красивые подсказки от IDE :)
Ну и это тоже
 

zerkms

TDD infected
Команда форума
partizan
фабрики нисколько не менее качественный код, нежели синглтоны с их явными интерфейсами :)
 

Mandor

Новичок
Как бы то ни было наследовать от синглтона плохая идея.
1. Наследование вам может еще пригодиться (а множественное наследование не поддерживается).
2. Не факт что потомки вашего класса (наследники синглтона) тоже должны быть синглтонами.
 

FractalizeR

Новичок
Это-то понятно. Мне непонятна суть фразы "Не факт что потомки вашего класса (наследники синглтона) тоже должны быть синглтонами." Если они "не должны быть синглтонами", то зачем я могу захотеть их от него унаследовать?
 

alex77

Новичок
я так делаю
PHP:
abstract class Singleton 
{
    private static $instances = array();
 
    protected function __construct() {}
    
    private function __clone() {
        trigger_error('Clone is not allowed.', E_USER_ERROR);
    }
 
    protected static function getInstanceOf($classname) {
        if(!isset(self::$instances[$classname])) {
            self::$instances[$classname] = new $classname(); 
        }
        return self::$instances[$classname];
    }
}
.............
class CSSequence extends Singleton
{
    
    public static function getInstance() {
        return self::getInstanceOf(__CLASS__);
    }
    
    protected function __construct() {}

..........
 

FractalizeR

Новичок
Я так понимаю, что в классе Singleton пропущено определение
public abstract static function getInstance();
 

alex77

Новичок
FractalizeR
оно вроде и не надо, на лётные качества не влияет
 
Сверху