liaren
@liaren
Фрилансер, опенсорсер, тех лид

Каким образом конфигурировать инициализацию Singleton-а?

Есть библиотека, в которой имеет место быть класс, у которого в рамках одного процесса позволительно существование только одного инстанса, т.е. фактически это Singleton. Беда в том, что инициализация этого самого инстанса имеет несколько динамических параметров, которые надо каким-то образом передавать.


Решение должно работать на PHP > 5.2. Единственное, что мне пришло на ум:

public static function init($params) {
		if(self::$instance) {
			throw new Exception(__CLASS__ . ' already initialized');
		}
		$class = __CLASS__;
		self::$instance = new $class($params);
	}

	public static function getInstance() {
		if(!self::$instance) {
			throw new Exception(__CLASS__ . ' is not initialized');
		}
		return self::$instance;
	}



Но оно кажется далеко не самым удачным. У кого-нибудь есть ещё какие идеи, паделитесь?

Спасибо!
  • Вопрос задан
  • 4853 просмотра
Пригласить эксперта
Ответы на вопрос 8
@LastDragon
Не привязываться к singleton-у (то что фактически существует всего один экземпляр не делает класс одиночкой, тем более учитывая что его поведение зависит от параметров конструктора). По-моему, наиболее логичным будет не использовать singleton, а единственный экземпляр этого класса хранить в registry (создание экземпляра будет где-то в коде, зависит от архитектуры вашего приложения).
Ответ написан
@Gron
en.wikipedia.org/wiki/Multiton_pattern
en.wikipedia.org/wiki/Immutable_object

Извиняюсь конечно но если нужны именно одиночки — юзайте Multition (онже пул одиночек), если хотите чтоб менялось состояние объекта который вы создали 1 раз — юзайте неизменяемый (Immutable)
Ответ написан
liaren
@liaren Автор вопроса
Фрилансер, опенсорсер, тех лид
Копия этого вопроса на StackOverflow: stackoverflow.com/questions/11081324/singleton-initialization-configuration
Ответ написан
Комментировать
gaelpa
@gaelpa
Если класс — синглтон, то и параметры его глобальны в рамках приложения или сеанса.
1. Может пусть он сам выясняет свою конфигурацию из внешнего источника?
2. Сделать метод/класс-обертку, собирающую (сама) параметры и передающую их в конструктор не-синглтона, после чего возвращающую тот же инстанс. Обертка на уровне приложения, так что инкапсуляция не страдает.
Ответ написан
Anonym
@Anonym
Программирую немного )
Тут есть пример синглтона на PHP
    public static function singleton()
    {
        if (!isset(self::$instance)) {
            echo 'Создание нового экземпляра.';
            $className = __CLASS__;
            self::$instance = new $className;
        }
        return self::$instance;
    }

Мне кажется очевидным сделать как-то так
    public static function singleton($params)

Собственно и получится примерно то, что вы и описали.
Мне кажется, это нормально.
Ответ написан
CrazySquirrel
@CrazySquirrel
<?
class MySingleton
{

        static private $_instance;

        private function __construct($params)
        {
                //При необходимости, недостающие параметры обработать тут.
                $this->_params = $params;
        }

        public static function getInstance()
        {
                if (!self::$_instance instanceof self) {
                        self::$_instance = new self(func_get_args());
                }

                return self::$_instance;
        }

        ...

}


MySingleton::getInstance('param1', 'param2', 'paramN')->doSomething();


А вообще это не кошерно.

Юзайте Registry.
Ответ написан
taliban
@taliban
php программист
Разделите конструктор и параметры:
class Singleton{
    static public punction getInstance(){ ... }
    public function applyParams($params){ ... }
}

$singleton = Singleton::getInstance()->applyParams($param1);
// some code
// change param
$singleton->applyParams($param2);
Ответ написан
AxisPod
@AxisPod
Я бы использовал статический метод для инициализации. И который кидал бы исключение в случае, если экземпляр уже создан.
Singleton::init(.....);
Singleton::getInstance()…
Singleton::init(....); // throw exception…
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы