MAXSITE.ORGКак сделать сайт своими руками

Шаблон Prototype (Прототип)

03-11-2019Время чтения ~ 2 мин.PHP/ООП 7030

Прототип — порождающий шаблон проектирования. Он используется для клонирования существующего объекта, вместо его инстанцирования с помощью new. Нам повезло, что в PHP уже есть всё необходимое для Prototype — это языковая конструкция clone, которая позволяет упростить реализацию праттерна до одной строчки.

Вообще может возникнуть вопрос, зачем вообще нужно клонирование, разве недостаточно обычного присваивания через равно «=»? Покажу на практическом примере.

Пусть у нас будет простой класс A с полем $val и двумя методами: один для установки значения поля, другой для его вывода.

class A {
	private $val;
 
	public function set($val)
	{
		$this->val = $val;
	}
	
	public function out()
	{
		echo $this->val;
	}
}

Теперь проверим как он работает:

// создаем объект
$a = new A;
 
// устанавливаем внутреннее поле 
$a->set('hello');
 
// вывод
$a->out(); // hello

Всё вполне ожидаемо. Теперь попробуем сделать копию объекта $a с помощью присваивания. Проверим что выводится в этом случае.

// получаем новую переменную $b
$b = $a;
 
// работаем с $b
$b->set('hi');
$b->out(); // hi
 
// проверяем что в $a
$a->out(); // hi

Неожиданно, так? Мы изменили объект $b, но он поменял и состояние поля в $a.

Так вот — в PHP операция присваивания объекта происходит по ссылке. То есть строчка $b = $a; не создала новый объект, а лишь указала, что $b ссылается на уже существующий $a. Поэтому все операции с этими переменными происходят с единым объектом.

Но что же делать, если действительно требуется создать совершенно новый объект/переменную? В PHP используется clone.

// создаем объект
$a = new A;
// устанавливаем внутреннее поле 
$a->set('hello');
// вывод
$a->out(); // hello
// клонирование
$c = clone $a;
// устанавливаем свой вариант
$c->set('hi');
// проверяем
$c->out(); // hi
$a->out(); // hello

Здесь переменная $c создана через клонирование другого объекта и после этого PHP будет считать их совершенно разными и несвязанными между собой.

Пример кода я разместил на гитхабе.

Клонирование может использоваться для случаев, когда нужно создать несколько объектов, инстанцирование которых затратная операция. В этом случае вначале делается один объект, происходит его начальная «тяжелая инициализация», а после объект клонируется для использования под разные задачи. Следует отметить, что в PHP копирование по ссылке для объектов сделано с целью оптимизации памяти, поскольку классы — достаточно сложные типы данных, которые требуют особого обращения. Поэтому клонирование — это способ быстрого получения отдельной копии, но за счёт дополнительного расхода памяти.

Похожие записи
Оставьте комментарий!
Сайт использует cookie
Для улучшения работы сайта собирается анонимная статистика через Google Analytics. Разрешить использование аналитических cookie?