Страницы

Поиск по вопросам

среда, 12 декабря 2018 г.

Как создать объект, если конструктор приватный?

Хочу понять, что здесь:
Требуется и нужно. Где такое реально применяется?
Код:
class S { private static $_instance = null; private $_x;
public function getX() { return $this->_x; }
public function setX($x) { $this->_x = $x; }
public static function getInstance() { if (!self::$_instance) { self::$_instance = new self; } return self::$_instance; }
private function __construct () { $this->setX(1); } }
$s1 = S::getInstance(); $s2 = S::getInstance();
/* вставьте сюда Ваш код создавать новые классы запрещено */
echo $s1->getX(); // должно вывести 1 echo $s2->getX(); // должно вывести 2


Ответ

Приведенный кусок кода, это реализация шаблона проектирования Одиночка (Singleton).
Шаблон Одиночка используется в случаях, когда в системе допускается использование какого-то объекта в единственном экземпляре. На практике это может быть полезно для реализации шаблона Реестр (Registry). Классическая реализация на PHP подразумевает три момента:
Реализацию статического метода получения экземпляра Одиночки
$a = S::getInstance(); Приватный конструктор Одиночки для запрета прямого создания экземпляров:
$a = new S(); // Ошибка Приватный метод __clone для запрета клонирования Одиночек
$a = S::getInstance(); $b = clone $a; // Ошибка
В приведенной вами реализации третий пункт пропущен, как следствие, вы спокойно можете использовать клонирование:
$s1 = S::getInstance(); $s2 = S::getInstance();
$s2 = clone $s1; $s2->setX(2);
echo $s1->getX(); // должно вывести 1 echo $s2->getX(); // должно вывести 2
Для справки:
Шаблон Реестр часто применяется, если в системе нужно централизованное хранилище какой-либо информации. Это могут быть как и некие настройки так и набор объектов-сервисов, которые используются повсеместно. Совсем не обязательно использовать связку Одиночка + Реестр. Можно передавать в экземпляр Реестра в явном виде в каждый класс, который в нем нуждается.

Комментариев нет:

Отправить комментарий