- PVSM.RU - https://www.pvsm.ru -

Реализация шаблона проектирования декоратор на PHP

Полагаю сам декоратор а так же причины по которым использование этого шаблона предпочтительней классическому наследованию в описании не нуждаются. При желании о нем можно прочитать в английской [1] или русской [2] википедии. imageПоэтому сама статья — это всего лишь мои соображений по поводу одной из возможных реализаций этого шаблона а именно динамического декорирования в противовес широко распространенной технике статического декорирования.

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

В английской статье Википедии про декоратор (ссылка выше) есть Java пример использования статического декорирования в реализации оконного интейрфеса. По аналогии того примера, но без использования классов декораторов:

class Window
{
	use TDecorator;
	
	private $title;
	
	function __construct($title)
	{
		$this->title = $title;
	}
	
	function draw()
	{
		// Draws window below
		// ...
		
		// Draws decorations. 
		$this->renderDecoration('draw');
	}
}

class VerticalScrollbar
{
	use TDecoration;
	
	private $vWidth;
	private $vHeight;
	
	function __construct($width, $height)
	{
		$this->vWidth = $width;
		$this->vHeight = $height;
	}
	
	function draw()
	{
		echo 'Drawing vertical scrollbar for the window "' . $this->title . ""n";
		echo 'Width: ' . $this->vWidth . "pxn";
		echo 'Height: ' . $this->vHeight . "pxn";
	}
}

// Decorates window with a vertical scrollbar.
$wnd = new Window('My application');
$wnd->decorateWithObject(new VerticalScrollbar(20, 20));
$wnd->draw();

При декорировании одного объекта другим он получает доступ не только ко всем его публичным и частным методам, но так же и свойствам вместе с их значениями. Можно сказать что таким способом класс VerticalScrollbar наследовал класс Window, но только для одного объекта.

Помимо декорирования одного объекта другим есть и более простая возможно добавлять новое поведение:

class Integer
{
	use TDecorator;
	protected $value;
	
	function __construct($value)
	{
		$this->value = intval($value);
	}
}

$integer = new Integer(9);
$integer->decorateWith('isOdd', function() {
	return (boolean) ($this->value % 2);
});
echo $integer->isOdd(); // echoes true

Реализацию декоратора в виде примеси можно найти здесь [3].

Надеюсь это небольшая статья кому-нибудь окажется полезной.

Автор: AccessGranted

Источник [4]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/php-2/25219

Ссылки в тексте:

[1] английской: http://en.wikipedia.org/wiki/Decorator_pattern

[2] русской: http://ru.wikipedia.org/wiki/%D0%94%D0%B5%D0%BA%D0%BE%D1%80%D0%B0%D1%82%D0%BE%D1%80_%28%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD_%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F%29

[3] здесь: http://pastebin.ca/2304831

[4] Источник: http://habrahabr.ru/post/166237/