Перейти к основному содержимому

Что это такое

Паттерн Приспособленец (Flyweight) экономит память, когда программа держит тысячи похожих объектов: тяжёлая разделяемая часть хранится один раз, и на неё ссылаются все, а каждый объект хранит только свою небольшую уникальную часть.

Лесу из 10 000 деревьев не нужно 10 000 текстур — нужны 2 вида деревьев и 10 000 крошечных записей (x, y, вид).


Пример: лес с разделяемыми видами

KindCache::get() выдаёт разделяемые объекты видов, создавая каждый только при первом запросе. Каждое дерево хранит лишь позицию и ссылку на свой вид.

Много деревьев, мало видов

Четыре дерева, но «создаётся вид» печатается лишь дважды — oak и pine существуют по одному экземпляру, каким бы большим ни стал лес. Объекты в PHP передаются по ссылке-дескриптору, поэтому каждое дерево вида oak указывает на один и тот же TreeKind.

Prompt
Напишите PHP-скрипт с паттерном Flyweight: тяжёлый класс TreeKind (name, texture), который хранится по одному экземпляру на вид в статическом массиве за методом KindCache::get(), печатающим сообщение при создании вида, и легковесные объекты Tree, содержащие только позицию и ссылку на свой вид. Посадите четыре дерева двух видов и напечатайте, сколько существует деревьев и сколько видов сохранено.
Вывод: PHP-скрипт

Когда применять

Применяйте, когда профилирование показывает проблемы с памятью из-за множества объектов, повторяющих тяжёлые данные — плитки карты, глифы, частицы, кэшированные стили.

Не применяйте, если объектов меньше тысяч или разделяемая часть невелика. Это паттерн оптимизации: без проблемы с памятью он даёт только сложность.


Плюсы и минусы

Плюсы: большая экономия памяти на масштабе; разделяемые данные обновляются в одном месте.

Минусы: разделяемые объекты нужно считать доступными только для чтения — одна неосторожная запись изменит «каждый дуб в лесу»; разделение на разделяемую и уникальную части усложняет модель.