PHP развернуть массив синглтон конструктор - PullRequest
1 голос
/ 04 февраля 2011

Я пытаюсь реализовать одноэлементный шаблон с возможностью передачи аргументов инструктору.Для одноэлементного шаблона я хочу создать базовый класс.Основная проблема заключается в том, что не все производные классы имеют одинаковое количество параметров.Для базового класса синглтона у меня пока есть это:

abstract class Singleton
{
    /**
     * Function: __construct
     * Description: the function which creates the object.
     */
    protected function __construct()
    {

    }
    private final function __clone()
    {
    }
    public static function getInstance()
    {
        $args = func_get_args();
        static $instance = null;

        return $instance = $instance ?  : new static();
    }
}    

Пока это работает, но я не могу передать аргументы конструктору с этим.Конечно, я могу напрямую передать массив $ args в конструктор, но я не хочу раскрывать массив в каждом конструкторе производных классов, я хочу иметь возможность передавать аргументы как обычные параметры.

Я уже пробовал несколько вещей: я пытался использовать call_user_func_array, но я не мог понять, как создать объект с помощью этой функции (если это вообще возможно), и я также попытался использовать ReflectionClass.Проблема с ReflectionClass заключалась в том, что этот класс не может получить доступ к конструктору, поскольку конструктор защищен.

Так у кого-нибудь есть какие-нибудь идеи для меня, как решить эту проблему?

пс.извините, если я веду себя сложно, но я просто пытаюсь найти лучшее решение (и понимаю это решение).

Ответы [ 2 ]

2 голосов
/ 04 февраля 2011

Во-первых, вам лучше использовать статическую переменную-член.А поскольку вы не можете динамически вызывать new, вы застряли, используя функцию init.

Как я бы это сделал:

abstract class Singleton
{
    protected static $instances = array();
    /**
     * Function: __construct
     * Description: the function which creates the object.
     */
    private function __construct()
    {
    }
    private final function __clone()
    {
    }

    protected abstract function _init();

    public static function getInstance()
    {
        $args = func_get_args();
        $class = strtolower(get_called_class());
        if (!isset(self::$instances[$class])) {
            self::$instances[$class] = new $class();
            call_user_func_array(
                array(
                    self::$instances[$class],
                    '_init'
                ),
                $args
            );
        }
        return self::$instances[$class];
    }
}

Итак, ваш расширяющий классбудет использовать _init вместо __construct:

class foo extends Singleton {
    protected function _init($foo) {
        $this->foo = $foo;
    }
}

Обратите внимание, что Singleton::__construct теперь является частным, чтобы предотвратить его неправильное использование.

Все это не соответствует факту, что1016 * одиночные являются злыми и должны быть избегаемыми .Так что, если вы должны их использовать, вы можете.Но найдите лучший способ, потому что они действительно такие плохие ...

1 голос
/ 04 февраля 2011

Если вы имеете в виду, что вам нужны некоторые настройки по умолчанию в вашем экземпляре, вы можете просто установить массив личных настроек в дочернем файле:

class Simpleton extends Singleton
{
  private $settings;

  protected function __construct()
  {
    $this->settings = array(
      //default settings here
    );
  }
}

Не пытайтесь включить параметры в синглтон. Если вам нужен параметризованный конструктор, не беспокойтесь об одиночном.

Синглтон должен иметь значения по умолчанию, а затем аксессоры / мутаторы для настройки любых настроек должны быть регулируемыми.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...