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

Вообще-то 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, при этом функционал, делающий класс синглтоном будет дублироваться во всех синглтонах), либо иметь фабрику, включающую в себя реестр, которая будет создавать обычные объекты, но в одном экземпляре и при повторном запросе отдавать уже созданный объект.
 
zerkms согласен :) Поглядел пару источников. Получается мешанина из Фабрик(или Одиночек) и Реестра. Кое-где это названо одной из разновидностей реестра. Да по барабану как это назвать :)
 
А нельзя ли фабрику попросить стать и реестром тоже? Я так понимаю, есть два варианта.
можно. тогда это будет 2 взаимодействующих паттерна. один строит объекты, другой предоставляет доступ к референсам. и всё это будет скрыто за одним общим интерфейсом. м?
 
Да уже проще после описания каждого класса сразу создавать экземплер в глобальную переменную, и его использовать.

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

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');
 
partizan
убери GLOBALS пока никто не увидел. я же писал - статический массив

function ...() {

static $instances;

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

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

myClass::getInstance();

vs

getInstance('myClass');

нету ::, есть '
в чём ещё разница?
 
zerkms ну если тока phpDoc и красивые подсказки от IDE :)
 
Adelf
ага, IDE взяла и разбежалась разрулить LSB. нуну :-)

(я писал фразу исходя из посыла, что в пхп 5.2 у нас такое колдунство работать не будет, а в 5.3 у нас подзнее связывание, которое происходит в рантайме)
 
Я не знаю что такое LSB.
Eclipse подсказывает когда знает что за класс и этот класс находится в данном проекте. С фабрико-реестром соответственно ничего не подскажет.
 
Adelf
Late Static Binding

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

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

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

Автор оригинала: Adelf
zerkms ну если тока phpDoc и красивые подсказки от IDE :)
Ну и это тоже
 
partizan
фабрики нисколько не менее качественный код, нежели синглтоны с их явными интерфейсами :-)
 
Как бы то ни было наследовать от синглтона плохая идея.
1. Наследование вам может еще пригодиться (а множественное наследование не поддерживается).
2. Не факт что потомки вашего класса (наследники синглтона) тоже должны быть синглтонами.
 
Это-то понятно. Мне непонятна суть фразы "Не факт что потомки вашего класса (наследники синглтона) тоже должны быть синглтонами." Если они "не должны быть синглтонами", то зачем я могу захотеть их от него унаследовать?
 
я так делаю
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() {}

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