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

Что это такое

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

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


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

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

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

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

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

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

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

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


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

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

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