Паттерн проектирования Приспособленец (Flyweight) на PHP 11.02.2011

Перед прочтением ознакомьтесь с введением в паттерны проектирования на PHP, в котором описаны принятые соглашения и понятия. Данная статья дополняется с некоторой периодичностью, так что если вы ее читали ранее, не факт что данные не изменились.
Приспособленец (Flyweight) относиться к классу структурных паттернов. Он используется для эффективной поддержки множества мелких объектов.
В некоторых приложения использование множества мелких объектов могло бы оказаться весьма полезным, однако прямая реализация ведет к чудовищному перерасходу ресурсов. Попробую объяснить это на примере интернет магазина, в котором мы будем продавать крутые дизайнерские подушки. С покупателями у нас не возникает проблем (так как подушки крутые), и список продаж все растет и растет. А так как это тешит наше самолюбие, вводить постраничность мы не спешим. И вот наступает тот момент, когда страница грузится достаточно долго, чтобы мы успели не только заскучать, но и совершить вечерний променад. Мы достигаем точки кипения и с большой неохотой пытаемся оптимизировать нашу архитектуру. Она из себя представляет собой набор объектов-продаж, включающего объект-покупатель и набор объектов-товаров. Где каждый объект-товар это совокупность таких параметров, как: артикул подушки, цвет подушки, цена, скидка.
Получается, что на каждую запись о продаже инстанцируется минимум 2 объекта (в зависимости от количества купленных подушек). В текущей реализации, порождение такого количества объектов излишне. Путем не сложных манипуляций можно объединить объект-покупатель и объект-товар в один объект продажа. На этом можно не останавливаться и свести все к одному объекту продажи.
Внося такие изменения мы не только теряем в гибкости и расширяемости, но и можем погрязнуть в устранении зависимостей. Решением этой проблемы может стать паттерн приспособленец.
Паттерн приспособленец позволяет повторно использовать мелкие объекты в различном контексте. В итоге мы сможем использовать в различных объектах-продажах одни и теже объекты-покупатели и объекты-товары. Как это работает на примере объекта-товара. У нас есть набор параметров (артикул подушки, цвет подушки, цена, скидка), которые полностью характеризуют этот товар. Соответственно, если у нас было несколько покупателей, которые выбрали одну и туже модель подушки, одного и того же цвета и попали под одну и туже скидку, то итоговые объекты-товары будут полностью идентичны. В итоге мы можем использовать один и тот же объект сразу в нескольких местах, что позволит сэкономить нам немного памяти. При достаточно большом количестве мелких объектов с малым количеством различающихся признаков, мы сможем получить весьма существенную экономию ресурсов. Итак, как структурно выглядит паттерн:

Где:
FlyweightFactory — модифицированный паттерн фабрика, для создания приспособленцев. Методу getFlyweight передаются признаки, по которым будет создан новый, либо найден и возвращен уже готовый объект.
Flyweight — абстрактный класс приспособленцев
ConcreteFlyweight — конкретная реализация приспособленца, которая будет замещать собой одинаковые мелкие объекты.
UnsharedFlyweight — реализация приспособленца, который не может быть разделен.
-
class FlyweightFactory
-
{
-
protected $_flyweigths = ();
-
-
/**
-
* @param string $key
-
* @return Flyweight
-
*/
-
-
public function getFlyweight($key)
-
{
-
// key может быть не только строкой, но и любым другим типом,
-
// в таком случае необходим иной способ поиска созданных приспособленцев
-
-
if (! (self::$_flyweigths[$key])) {
-
// здесь могут быть условия, когда создавать обычного приспособленца,
-
// а когда возвращать неделимого
-
-
self::$_flyweigths[$key] = new ConcreteFlyweight();
-
}
-
-
return self::$_flyweigths[$key];
-
}
-
}
-
-
abstract class Flyweight
-
{
-
/**
-
* @var mixed внутреннее состояние
-
*/
-
-
protected $_intrinsicState = null;
-
-
/**
-
* @param mixed $extrinsicState
-
* внешнее состояние, передаваемое в приспособленец (контекст)
-
*/
-
-
public function Operation($extrinsicState)
-
{
-
//...
-
}
-
}
-
-
class ConcreteFlyweight extends Flyweight {}
-
class UnsharedFlyweight extends Flyweight {}
Скачать исходный код можно тут.
Паттерн приспособленец зачастую используется вместе c паттерном компоновщик, для реализации иерархической структуры в виде ациклического направленного графа с разделяемыми листовыми вершинами.
Похожие статьи
- Паттерн проектирования Прокси (Proxy) на PHP
- Вышел PHP 5.4a1
- Как закрыть соединение и продолжить выполнение скрипта
- Встроенный Web сервер в PHP
- Вышел NetBeans 7 Beta 2
