Страницы

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

воскресенье, 29 декабря 2019 г.

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

#php #шаблоны_проектирования


Хочу понять, что здесь:


Требуется и нужно.
Где такое реально применяется?


Код:

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

    


Ответы

Ответ 1



Приведенный кусок кода, это реализация шаблона проектирования Одиночка (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 Для справки: Шаблон Реестр часто применяется, если в системе нужно централизованное хранилище какой-либо информации. Это могут быть как и некие настройки так и набор объектов-сервисов, которые используются повсеместно. Совсем не обязательно использовать связку Одиночка + Реестр. Можно передавать в экземпляр Реестра в явном виде в каждый класс, который в нем нуждается.

Ответ 2



Приватный конструктор плюс создающая функция нужны для контроля над созданием объекта. Это по существу паттерн «фабрика» или одна из его разновидностей. Используется, например, если вы хотите иметь несколько возможностей инициализации объекта. В данном случае использование контроля над созданием используется с другой целью. Код реализует синглтон: функция getInstance заботится о том, чтобы было создан лишь один объект, и каждый запрос получал всё время этот же объект. Приватный конструктор не позволяет чужому коду создать свой экземпляр объекта. Синглтон нужен, например, если у вас какой-то объект должен существовать лишь в единственном числе, (и создавать его заранее вы не хотите по каким-либо причинам). Как заставить код вывести 2 для второй строчки, не знаю.

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

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