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

Что это такое

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

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


Пример: лес с общими видами

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

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

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

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

Когда его использовать

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

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


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

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

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